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