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