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