-import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
-import { logger } from '../../helpers'
+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 { AttributesOnly } from '@shared/typescript-utils'
+import { logger } from '../../helpers/logger'
import { AccountModel } from '../account/account'
-import { UserModel } from '../account/user'
+import { ActorModel } from '../actor/actor'
+import { UserModel } from '../user/user'
import { OAuthClientModel } from './oauth-client'
export type OAuthTokenInfo = {
refreshToken: string
- refreshTokenExpiresAt: Date,
+ refreshTokenExpiresAt: Date
client: {
id: number
- },
- user: {
- id: number
}
+ user: MUserAccountId
+ token: MOAuthTokenUser
}
+enum ScopeNames {
+ WITH_USER = 'WITH_USER'
+}
+
+@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: [
}
]
})
-export class OAuthTokenModel extends Model<OAuthTokenModel> {
+export class OAuthTokenModel extends Model<Partial<AttributesOnly<OAuthTokenModel>>> {
@AllowNull(false)
@Column
@Column
refreshTokenExpiresAt: Date
+ @Column
+ authName: string
+
@CreatedAt
createdAt: Date
})
OAuthClients: OAuthClientModel[]
+ @AfterUpdate
+ @AfterDestroy
+ static removeTokenCache (token: OAuthTokenModel) {
+ return TokensCache.Instance.clearCacheByToken(token.accessToken)
+ }
+
+ static loadByRefreshToken (refreshToken: string) {
+ const query = {
+ where: { refreshToken }
+ }
+
+ return OAuthTokenModel.findOne(query)
+ }
+
static getByRefreshTokenAndPopulateClient (refreshToken: string) {
const query = {
where: {
- refreshToken: refreshToken
+ refreshToken
},
include: [ OAuthClientModel ]
}
- return OAuthTokenModel.findOne(query)
- .then(token => {
- if (!token) return null
-
- return {
- refreshToken: token.refreshToken,
- refreshTokenExpiresAt: token.refreshTokenExpiresAt,
- client: {
- id: token.oAuthClientId
- },
- user: {
- id: token.userId
- }
- } as OAuthTokenInfo
- })
- .catch(err => {
- logger.info('getRefreshToken error.', err)
- throw err
- })
+ 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) {
+ static getByTokenAndPopulateUser (bearerToken: string): Promise<MOAuthTokenUser> {
const query = {
where: {
accessToken: bearerToken
- },
- include: [
- {
- model: UserModel,
- include: [
- {
- model: AccountModel,
- required: true
- }
- ]
- }
- ]
+ }
}
- return OAuthTokenModel.findOne(query).then(token => {
- if (token) token['user'] = token.User
+ return OAuthTokenModel.scope(ScopeNames.WITH_USER)
+ .findOne(query)
+ .then(token => {
+ if (!token) return null
- return token
- })
+ return Object.assign(token, { user: token.User })
+ })
}
- static getByRefreshTokenAndPopulateUser (refreshToken: string) {
+ static getByRefreshTokenAndPopulateUser (refreshToken: string): Promise<MOAuthTokenUser> {
const query = {
where: {
- refreshToken: refreshToken
- },
- include: [
- {
- model: UserModel,
- include: [
- {
- model: AccountModel,
- required: true
- }
- ]
- }
- ]
+ refreshToken
+ }
}
- return OAuthTokenModel.findOne(query).then(token => {
- token['user'] = token.User
+ return OAuthTokenModel.scope(ScopeNames.WITH_USER)
+ .findOne(query)
+ .then(token => {
+ if (!token) return undefined
+
+ return Object.assign(token, { user: token.User })
+ })
+ }
+
+ static deleteUserToken (userId: number, t?: Transaction) {
+ TokensCache.Instance.deleteUserToken(userId)
+
+ const query = {
+ where: {
+ userId
+ },
+ transaction: t
+ }
- return token
- })
+ return OAuthTokenModel.destroy(query)
}
}