X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Foauth%2Foauth-token.ts;h=27e643aa71cf0aba93e18fb8a15d4903d6c36c2a;hb=e62f03ae0412f4efa62917d8741bc1a39e8ed7fc;hp=eab9cf8580a205ae4388d110c0b84904e1f918fc;hpb=74889a71fe687dda74f2a687653122327807af36;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index eab9cf858..27e643aa7 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts @@ -1,160 +1,219 @@ -import * as Sequelize from 'sequelize' +import { Transaction } from 'sequelize' +import { + AfterDestroy, + AfterUpdate, + AllowNull, + BelongsTo, + Column, + CreatedAt, + ForeignKey, + Model, + Scopes, + Table, + UpdatedAt +} from 'sequelize-typescript' +import { TokensCache } from '@server/lib/auth/tokens-cache' +import { MUserAccountId } from '@server/types/models' +import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token' +import { logger } from '../../helpers/logger' +import { AccountModel } from '../account/account' +import { UserModel } from '../account/user' +import { ActorModel } from '../activitypub/actor' +import { OAuthClientModel } from './oauth-client' + +export type OAuthTokenInfo = { + refreshToken: string + refreshTokenExpiresAt: Date + client: { + id: number + } + user: MUserAccountId + token: MOAuthTokenUser +} -import { logger } from '../../helpers' +enum ScopeNames { + WITH_USER = 'WITH_USER' +} -import { addMethodsToModel } from '../utils' -import { - OAuthTokenClass, - OAuthTokenInstance, - OAuthTokenAttributes, - - OAuthTokenMethods, - OAuthTokenInfo -} from './oauth-token-interface' - -let OAuthToken: Sequelize.Model -let getByRefreshTokenAndPopulateClient: OAuthTokenMethods.GetByRefreshTokenAndPopulateClient -let getByTokenAndPopulateUser: OAuthTokenMethods.GetByTokenAndPopulateUser -let getByRefreshTokenAndPopulateUser: OAuthTokenMethods.GetByRefreshTokenAndPopulateUser -let removeByUserId: OAuthTokenMethods.RemoveByUserId - -export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { - OAuthToken = sequelize.define('OAuthToken', - { - accessToken: { - type: DataTypes.STRING, - allowNull: false - }, - accessTokenExpiresAt: { - type: DataTypes.DATE, - allowNull: false - }, - refreshToken: { - type: DataTypes.STRING, - allowNull: false - }, - refreshTokenExpiresAt: { - type: DataTypes.DATE, - allowNull: false +@Scopes(() => ({ + [ScopeNames.WITH_USER]: { + include: [ + { + model: UserModel.unscoped(), + required: true, + include: [ + { + attributes: [ 'id' ], + model: AccountModel.unscoped(), + required: true, + include: [ + { + attributes: [ 'id', 'url' ], + model: ActorModel.unscoped(), + required: true + } + ] + } + ] } + ] + } +})) +@Table({ + tableName: 'oAuthToken', + indexes: [ + { + fields: [ 'refreshToken' ], + unique: true }, { - indexes: [ - { - fields: [ 'refreshToken' ], - unique: true - }, - { - fields: [ 'accessToken' ], - unique: true - }, - { - fields: [ 'userId' ] - }, - { - fields: [ 'oAuthClientId' ] - } - ] + fields: [ 'accessToken' ], + unique: true + }, + { + fields: [ 'userId' ] + }, + { + fields: [ 'oAuthClientId' ] } - ) + ] +}) +export class OAuthTokenModel extends Model { - const classMethods = [ - associate, + @AllowNull(false) + @Column + accessToken: string - getByRefreshTokenAndPopulateClient, - getByTokenAndPopulateUser, - getByRefreshTokenAndPopulateUser, - removeByUserId - ] - addMethodsToModel(OAuthToken, classMethods) + @AllowNull(false) + @Column + accessTokenExpiresAt: Date - return OAuthToken -} + @AllowNull(false) + @Column + refreshToken: string -// --------------------------------------------------------------------------- + @AllowNull(false) + @Column + refreshTokenExpiresAt: Date -function associate (models) { - OAuthToken.belongsTo(models.User, { + @Column + authName: string + + @CreatedAt + createdAt: Date + + @UpdatedAt + updatedAt: Date + + @ForeignKey(() => UserModel) + @Column + userId: number + + @BelongsTo(() => UserModel, { foreignKey: { - name: 'userId', allowNull: false }, onDelete: 'cascade' }) + User: UserModel + + @ForeignKey(() => OAuthClientModel) + @Column + oAuthClientId: number - OAuthToken.belongsTo(models.OAuthClient, { + @BelongsTo(() => OAuthClientModel, { foreignKey: { - name: 'oAuthClientId', allowNull: false }, onDelete: 'cascade' }) -} + OAuthClients: OAuthClientModel[] -getByRefreshTokenAndPopulateClient = function (refreshToken: string) { - const query = { - where: { - refreshToken: refreshToken - }, - include: [ OAuthToken['sequelize'].models.OAuthClient ] + @AfterUpdate + @AfterDestroy + static removeTokenCache (token: OAuthTokenModel) { + return TokensCache.Instance.clearCacheByToken(token.accessToken) } - return OAuthToken.findOne(query).then(function (token) { - if (!token) return null + static loadByRefreshToken (refreshToken: string) { + const query = { + where: { refreshToken } + } + + return OAuthTokenModel.findOne(query) + } - const tokenInfos: OAuthTokenInfo = { - refreshToken: token.refreshToken, - refreshTokenExpiresAt: token.refreshTokenExpiresAt, - client: { - id: token['client'].id + static getByRefreshTokenAndPopulateClient (refreshToken: string) { + const query = { + where: { + refreshToken }, - user: { - id: token['user'] + include: [ OAuthClientModel ] + } + + return OAuthTokenModel.scope(ScopeNames.WITH_USER) + .findOne(query) + .then(token => { + if (!token) return null + + return { + refreshToken: token.refreshToken, + refreshTokenExpiresAt: token.refreshTokenExpiresAt, + client: { + id: token.oAuthClientId + }, + user: token.User, + token + } as OAuthTokenInfo + }) + .catch(err => { + logger.error('getRefreshToken error.', { err }) + throw err + }) + } + + static getByTokenAndPopulateUser (bearerToken: string): Promise { + const query = { + where: { + accessToken: bearerToken } } - return tokenInfos - }).catch(function (err) { - logger.info('getRefreshToken error.', { error: err }) - }) -} + return OAuthTokenModel.scope(ScopeNames.WITH_USER) + .findOne(query) + .then(token => { + if (!token) return null -getByTokenAndPopulateUser = function (bearerToken: string) { - const query = { - where: { - accessToken: bearerToken - }, - include: [ OAuthToken['sequelize'].models.User ] + return Object.assign(token, { user: token.User }) + }) } - return OAuthToken.findOne(query).then(function (token) { - if (token) token['user'] = token.User + static getByRefreshTokenAndPopulateUser (refreshToken: string): Promise { + const query = { + where: { + refreshToken + } + } - return token - }) -} + return OAuthTokenModel.scope(ScopeNames.WITH_USER) + .findOne(query) + .then(token => { + if (!token) return undefined -getByRefreshTokenAndPopulateUser = function (refreshToken: string) { - const query = { - where: { - refreshToken: refreshToken - }, - include: [ OAuthToken['sequelize'].models.User ] + return Object.assign(token, { user: token.User }) + }) } - return OAuthToken.findOne(query).then(function (token) { - token['user'] = token.User + static deleteUserToken (userId: number, t?: Transaction) { + TokensCache.Instance.deleteUserToken(userId) - return token - }) -} - -removeByUserId = function (userId, callback) { - const query = { - where: { - userId: userId + const query = { + where: { + userId + }, + transaction: t } - } - return OAuthToken.destroy(query).asCallback(callback) + return OAuthTokenModel.destroy(query) + } }