OAuth2 access token cleanup

master
rob 2 years ago
parent a10dde0f9a
commit 7cb886d220

@ -8,11 +8,20 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const OAuth2AccessTokenSchema = new Schema({
token: { type: String, required: true, unique: true, index: 1 },
const OAuth2TokenSchema = new Schema({
type: { type: String, enum: ['access','refresh'], required: true },
token: { type: String, required: true },
user: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' },
client: { type: Schema.ObjectId, required: true, index: 1, ref: 'OAuth2Client' },
scope: { type: [String], required: true },
});
});
module.exports = mongoose.model('OAuth2AccessToken', OAuth2AccessTokenSchema);
OAuth2TokenSchema.index({
type: 1,
token: 1,
}, {
unique: true,
name: 'oauth2_token_unique',
});
module.exports = mongoose.model('OAuth2Token', OAuth2TokenSchema);

@ -8,7 +8,7 @@ const mongoose = require('mongoose');
const OAuth2Client = mongoose.model('OAuth2Client');
const OAuth2AuthorizationCode = mongoose.model('OAuth2AuthorizationCode');
const OAuth2AccessToken = mongoose.model('OAuth2AccessToken');
const OAuth2Token = mongoose.model('OAuth2Token');
const uuidv4 = require('uuid').v4;
const striptags = require('striptags');
@ -28,7 +28,7 @@ class OAuth2Service extends SiteService {
constructor (dtp) {
super(dtp, module.exports);
this.populateOAuth2AccessToken = [
this.populateOAuth2Token = [
{
path: 'user',
select: 'username username_lc displayName picture',
@ -47,7 +47,7 @@ class OAuth2Service extends SiteService {
this.log.info('registering OAuth2 action handlers');
this.server.grant(oauth2orize.grant.code(this.processGrant.bind(this)));
this.server.exchange(oauth2orize.exchange.code(this.processExchange.bind(this)));
this.server.exchange(oauth2orize.exchange.code(this.processExchangeCode.bind(this)));
this.log.info('registering OAuth2 serialization routines');
this.server.serializeClient(this.serializeClient.bind(this));
@ -168,7 +168,40 @@ class OAuth2Service extends SiteService {
}
}
async processExchange (client, code, redirectUri, done) {
async issueTokens (authCode) {
const response = {
params: {
coreUserId: authCode.user._id,
username: authCode.user.username,
username_lc: authCode.user.username_lc,
displayName: authCode.user.displayName,
bio: authCode.user.bio,
permissions: authCode.user.permissions,
flags: authCode.user.flags,
},
accessToken: generatePassword(256, false),
refreshToken: generatePassword(256, false),
};
await Promise.all([
OAuth2Token.create({
type: 'access',
token: response.accessToken,
user: authCode.user._id,
client: authCode.client._id,
scope: authCode.scope,
}),
OAuth2Token.create({
type: 'refresh',
token: response.refreshToken,
user: authCode.user._id,
client: authCode.client._id,
scope: authCode.scope,
}),
]);
return response;
}
async processExchangeCode (client, code, redirectUri, done) {
try {
const ac = await OAuth2AuthorizationCode
.findOne({ code })
@ -178,7 +211,7 @@ class OAuth2Service extends SiteService {
},
{
path: 'user',
select: 'username username_lc displayName picture',
select: 'username username_lc displayName picture bio permissions flags',
},
]);
@ -190,18 +223,10 @@ class OAuth2Service extends SiteService {
this.log.alert('OAuth2 redirect mismatch', { provided: redirectUri, onfile: ac.redirectUri });
return done(null, false);
}
var token = uuidv4();
var at = new OAuth2AccessToken({
token,
user: ac.user._id,
client: ac.client._id,
scope: ac.scope,
});
await at.save();
const response = await this.issueTokens(ac);
this.log.info('OAuth2 grant exchanged for token', { clientID: client._id });
return done(null, token);
return done(null, response.accessToken, response.refreshToken, response.params);
} catch (error) {
this.log.error('failed to process OAuth2 exchange', { error });
return done(error);
@ -306,9 +331,9 @@ class OAuth2Service extends SiteService {
}
async getAccessToken (accessToken) {
const token = await OAuth2AccessToken
.findOne({ token: accessToken })
.populate(this.populateOAuth2AccessToken)
const token = await OAuth2Token
.findOne({ type: 'access', token: accessToken })
.populate(this.populateOAuth2Token)
.lean();
return token;
}

Loading…
Cancel
Save