]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/oauth/oauth-token.ts
Cleanup models directory organization
[github/Chocobozzz/PeerTube.git] / server / models / oauth / oauth-token.ts
1 import { Transaction } from 'sequelize'
2 import {
3 AfterDestroy,
4 AfterUpdate,
5 AllowNull,
6 BelongsTo,
7 Column,
8 CreatedAt,
9 ForeignKey,
10 Model,
11 Scopes,
12 Table,
13 UpdatedAt
14 } from 'sequelize-typescript'
15 import { TokensCache } from '@server/lib/auth/tokens-cache'
16 import { MUserAccountId } from '@server/types/models'
17 import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token'
18 import { logger } from '../../helpers/logger'
19 import { AccountModel } from '../account/account'
20 import { ActorModel } from '../actor/actor'
21 import { UserModel } from '../user/user'
22 import { OAuthClientModel } from './oauth-client'
23
24 export type OAuthTokenInfo = {
25 refreshToken: string
26 refreshTokenExpiresAt: Date
27 client: {
28 id: number
29 }
30 user: MUserAccountId
31 token: MOAuthTokenUser
32 }
33
34 enum ScopeNames {
35 WITH_USER = 'WITH_USER'
36 }
37
38 @Scopes(() => ({
39 [ScopeNames.WITH_USER]: {
40 include: [
41 {
42 model: UserModel.unscoped(),
43 required: true,
44 include: [
45 {
46 attributes: [ 'id' ],
47 model: AccountModel.unscoped(),
48 required: true,
49 include: [
50 {
51 attributes: [ 'id', 'url' ],
52 model: ActorModel.unscoped(),
53 required: true
54 }
55 ]
56 }
57 ]
58 }
59 ]
60 }
61 }))
62 @Table({
63 tableName: 'oAuthToken',
64 indexes: [
65 {
66 fields: [ 'refreshToken' ],
67 unique: true
68 },
69 {
70 fields: [ 'accessToken' ],
71 unique: true
72 },
73 {
74 fields: [ 'userId' ]
75 },
76 {
77 fields: [ 'oAuthClientId' ]
78 }
79 ]
80 })
81 export class OAuthTokenModel extends Model {
82
83 @AllowNull(false)
84 @Column
85 accessToken: string
86
87 @AllowNull(false)
88 @Column
89 accessTokenExpiresAt: Date
90
91 @AllowNull(false)
92 @Column
93 refreshToken: string
94
95 @AllowNull(false)
96 @Column
97 refreshTokenExpiresAt: Date
98
99 @Column
100 authName: string
101
102 @CreatedAt
103 createdAt: Date
104
105 @UpdatedAt
106 updatedAt: Date
107
108 @ForeignKey(() => UserModel)
109 @Column
110 userId: number
111
112 @BelongsTo(() => UserModel, {
113 foreignKey: {
114 allowNull: false
115 },
116 onDelete: 'cascade'
117 })
118 User: UserModel
119
120 @ForeignKey(() => OAuthClientModel)
121 @Column
122 oAuthClientId: number
123
124 @BelongsTo(() => OAuthClientModel, {
125 foreignKey: {
126 allowNull: false
127 },
128 onDelete: 'cascade'
129 })
130 OAuthClients: OAuthClientModel[]
131
132 @AfterUpdate
133 @AfterDestroy
134 static removeTokenCache (token: OAuthTokenModel) {
135 return TokensCache.Instance.clearCacheByToken(token.accessToken)
136 }
137
138 static loadByRefreshToken (refreshToken: string) {
139 const query = {
140 where: { refreshToken }
141 }
142
143 return OAuthTokenModel.findOne(query)
144 }
145
146 static getByRefreshTokenAndPopulateClient (refreshToken: string) {
147 const query = {
148 where: {
149 refreshToken
150 },
151 include: [ OAuthClientModel ]
152 }
153
154 return OAuthTokenModel.scope(ScopeNames.WITH_USER)
155 .findOne(query)
156 .then(token => {
157 if (!token) return null
158
159 return {
160 refreshToken: token.refreshToken,
161 refreshTokenExpiresAt: token.refreshTokenExpiresAt,
162 client: {
163 id: token.oAuthClientId
164 },
165 user: token.User,
166 token
167 } as OAuthTokenInfo
168 })
169 .catch(err => {
170 logger.error('getRefreshToken error.', { err })
171 throw err
172 })
173 }
174
175 static getByTokenAndPopulateUser (bearerToken: string): Promise<MOAuthTokenUser> {
176 const query = {
177 where: {
178 accessToken: bearerToken
179 }
180 }
181
182 return OAuthTokenModel.scope(ScopeNames.WITH_USER)
183 .findOne(query)
184 .then(token => {
185 if (!token) return null
186
187 return Object.assign(token, { user: token.User })
188 })
189 }
190
191 static getByRefreshTokenAndPopulateUser (refreshToken: string): Promise<MOAuthTokenUser> {
192 const query = {
193 where: {
194 refreshToken
195 }
196 }
197
198 return OAuthTokenModel.scope(ScopeNames.WITH_USER)
199 .findOne(query)
200 .then(token => {
201 if (!token) return undefined
202
203 return Object.assign(token, { user: token.User })
204 })
205 }
206
207 static deleteUserToken (userId: number, t?: Transaction) {
208 TokensCache.Instance.deleteUserToken(userId)
209
210 const query = {
211 where: {
212 userId
213 },
214 transaction: t
215 }
216
217 return OAuthTokenModel.destroy(query)
218 }
219 }