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