diff options
Diffstat (limited to 'server/models/oauth')
-rw-r--r-- | server/models/oauth/index.ts | 2 | ||||
-rw-r--r-- | server/models/oauth/oauth-client-interface.ts | 31 | ||||
-rw-r--r-- | server/models/oauth/oauth-client.ts | 112 | ||||
-rw-r--r-- | server/models/oauth/oauth-token-interface.ts | 46 | ||||
-rw-r--r-- | server/models/oauth/oauth-token.ts | 259 |
5 files changed, 173 insertions, 277 deletions
diff --git a/server/models/oauth/index.ts b/server/models/oauth/index.ts deleted file mode 100644 index a20d3a56a..000000000 --- a/server/models/oauth/index.ts +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | export * from './oauth-client-interface' | ||
2 | export * from './oauth-token-interface' | ||
diff --git a/server/models/oauth/oauth-client-interface.ts b/server/models/oauth/oauth-client-interface.ts deleted file mode 100644 index 3526e4159..000000000 --- a/server/models/oauth/oauth-client-interface.ts +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import * as Promise from 'bluebird' | ||
3 | |||
4 | export namespace OAuthClientMethods { | ||
5 | export type CountTotal = () => Promise<number> | ||
6 | |||
7 | export type LoadFirstClient = () => Promise<OAuthClientInstance> | ||
8 | |||
9 | export type GetByIdAndSecret = (clientId: string, clientSecret: string) => Promise<OAuthClientInstance> | ||
10 | } | ||
11 | |||
12 | export interface OAuthClientClass { | ||
13 | countTotal: OAuthClientMethods.CountTotal | ||
14 | loadFirstClient: OAuthClientMethods.LoadFirstClient | ||
15 | getByIdAndSecret: OAuthClientMethods.GetByIdAndSecret | ||
16 | } | ||
17 | |||
18 | export interface OAuthClientAttributes { | ||
19 | clientId: string | ||
20 | clientSecret: string | ||
21 | grants: string[] | ||
22 | redirectUris: string[] | ||
23 | } | ||
24 | |||
25 | export interface OAuthClientInstance extends OAuthClientClass, OAuthClientAttributes, Sequelize.Instance<OAuthClientAttributes> { | ||
26 | id: number | ||
27 | createdAt: Date | ||
28 | updatedAt: Date | ||
29 | } | ||
30 | |||
31 | export interface OAuthClientModel extends OAuthClientClass, Sequelize.Model<OAuthClientInstance, OAuthClientAttributes> {} | ||
diff --git a/server/models/oauth/oauth-client.ts b/server/models/oauth/oauth-client.ts index 9cc68771d..42c59bb79 100644 --- a/server/models/oauth/oauth-client.ts +++ b/server/models/oauth/oauth-client.ts | |||
@@ -1,86 +1,62 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import { AllowNull, Column, CreatedAt, DataType, HasMany, Model, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { OAuthTokenModel } from './oauth-token' | ||
2 | 3 | ||
3 | import { addMethodsToModel } from '../utils' | 4 | @Table({ |
4 | import { | 5 | tableName: 'oAuthClient', |
5 | OAuthClientInstance, | 6 | indexes: [ |
6 | OAuthClientAttributes, | ||
7 | |||
8 | OAuthClientMethods | ||
9 | } from './oauth-client-interface' | ||
10 | |||
11 | let OAuthClient: Sequelize.Model<OAuthClientInstance, OAuthClientAttributes> | ||
12 | let countTotal: OAuthClientMethods.CountTotal | ||
13 | let loadFirstClient: OAuthClientMethods.LoadFirstClient | ||
14 | let getByIdAndSecret: OAuthClientMethods.GetByIdAndSecret | ||
15 | |||
16 | export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { | ||
17 | OAuthClient = sequelize.define<OAuthClientInstance, OAuthClientAttributes>('OAuthClient', | ||
18 | { | 7 | { |
19 | clientId: { | 8 | fields: [ 'clientId' ], |
20 | type: DataTypes.STRING, | 9 | unique: true |
21 | allowNull: false | ||
22 | }, | ||
23 | clientSecret: { | ||
24 | type: DataTypes.STRING, | ||
25 | allowNull: false | ||
26 | }, | ||
27 | grants: { | ||
28 | type: DataTypes.ARRAY(DataTypes.STRING) | ||
29 | }, | ||
30 | redirectUris: { | ||
31 | type: DataTypes.ARRAY(DataTypes.STRING) | ||
32 | } | ||
33 | }, | 10 | }, |
34 | { | 11 | { |
35 | indexes: [ | 12 | fields: [ 'clientId', 'clientSecret' ], |
36 | { | 13 | unique: true |
37 | fields: [ 'clientId' ], | ||
38 | unique: true | ||
39 | }, | ||
40 | { | ||
41 | fields: [ 'clientId', 'clientSecret' ], | ||
42 | unique: true | ||
43 | } | ||
44 | ] | ||
45 | } | 14 | } |
46 | ) | 15 | ] |
16 | }) | ||
17 | export class OAuthClientModel extends Model<OAuthClientModel> { | ||
47 | 18 | ||
48 | const classMethods = [ | 19 | @AllowNull(false) |
49 | associate, | 20 | @Column |
21 | clientId: string | ||
50 | 22 | ||
51 | countTotal, | 23 | @AllowNull(false) |
52 | getByIdAndSecret, | 24 | @Column |
53 | loadFirstClient | 25 | clientSecret: string |
54 | ] | ||
55 | addMethodsToModel(OAuthClient, classMethods) | ||
56 | 26 | ||
57 | return OAuthClient | 27 | @Column(DataType.ARRAY(DataType.STRING)) |
58 | } | 28 | grants: string[] |
29 | |||
30 | @Column(DataType.ARRAY(DataType.STRING)) | ||
31 | redirectUris: string[] | ||
32 | |||
33 | @CreatedAt | ||
34 | createdAt: Date | ||
59 | 35 | ||
60 | // --------------------------------------------------------------------------- | 36 | @UpdatedAt |
37 | updatedAt: Date | ||
61 | 38 | ||
62 | function associate (models) { | 39 | @HasMany(() => OAuthTokenModel, { |
63 | OAuthClient.hasMany(models.OAuthToken, { | ||
64 | foreignKey: 'oAuthClientId', | ||
65 | onDelete: 'cascade' | 40 | onDelete: 'cascade' |
66 | }) | 41 | }) |
67 | } | 42 | OAuthTokens: OAuthTokenModel[] |
68 | 43 | ||
69 | countTotal = function () { | 44 | static countTotal () { |
70 | return OAuthClient.count() | 45 | return OAuthClientModel.count() |
71 | } | 46 | } |
72 | 47 | ||
73 | loadFirstClient = function () { | 48 | static loadFirstClient () { |
74 | return OAuthClient.findOne() | 49 | return OAuthClientModel.findOne() |
75 | } | 50 | } |
76 | 51 | ||
77 | getByIdAndSecret = function (clientId: string, clientSecret: string) { | 52 | static getByIdAndSecret (clientId: string, clientSecret: string) { |
78 | const query = { | 53 | const query = { |
79 | where: { | 54 | where: { |
80 | clientId: clientId, | 55 | clientId: clientId, |
81 | clientSecret: clientSecret | 56 | clientSecret: clientSecret |
57 | } | ||
82 | } | 58 | } |
83 | } | ||
84 | 59 | ||
85 | return OAuthClient.findOne(query) | 60 | return OAuthClientModel.findOne(query) |
61 | } | ||
86 | } | 62 | } |
diff --git a/server/models/oauth/oauth-token-interface.ts b/server/models/oauth/oauth-token-interface.ts deleted file mode 100644 index 47d95d5fc..000000000 --- a/server/models/oauth/oauth-token-interface.ts +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | import * as Promise from 'bluebird' | ||
2 | import * as Sequelize from 'sequelize' | ||
3 | |||
4 | import { UserModel } from '../account/user-interface' | ||
5 | |||
6 | export type OAuthTokenInfo = { | ||
7 | refreshToken: string | ||
8 | refreshTokenExpiresAt: Date, | ||
9 | client: { | ||
10 | id: number | ||
11 | }, | ||
12 | user: { | ||
13 | id: number | ||
14 | } | ||
15 | } | ||
16 | |||
17 | export namespace OAuthTokenMethods { | ||
18 | export type GetByRefreshTokenAndPopulateClient = (refreshToken: string) => Promise<OAuthTokenInfo> | ||
19 | export type GetByTokenAndPopulateUser = (bearerToken: string) => Promise<OAuthTokenInstance> | ||
20 | export type GetByRefreshTokenAndPopulateUser = (refreshToken: string) => Promise<OAuthTokenInstance> | ||
21 | } | ||
22 | |||
23 | export interface OAuthTokenClass { | ||
24 | getByRefreshTokenAndPopulateClient: OAuthTokenMethods.GetByRefreshTokenAndPopulateClient | ||
25 | getByTokenAndPopulateUser: OAuthTokenMethods.GetByTokenAndPopulateUser | ||
26 | getByRefreshTokenAndPopulateUser: OAuthTokenMethods.GetByRefreshTokenAndPopulateUser | ||
27 | } | ||
28 | |||
29 | export interface OAuthTokenAttributes { | ||
30 | accessToken: string | ||
31 | accessTokenExpiresAt: Date | ||
32 | refreshToken: string | ||
33 | refreshTokenExpiresAt: Date | ||
34 | |||
35 | userId?: number | ||
36 | oAuthClientId?: number | ||
37 | User?: UserModel | ||
38 | } | ||
39 | |||
40 | export interface OAuthTokenInstance extends OAuthTokenClass, OAuthTokenAttributes, Sequelize.Instance<OAuthTokenAttributes> { | ||
41 | id: number | ||
42 | createdAt: Date | ||
43 | updatedAt: Date | ||
44 | } | ||
45 | |||
46 | export interface OAuthTokenModel extends OAuthTokenClass, Sequelize.Model<OAuthTokenInstance, OAuthTokenAttributes> {} | ||
diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index a82bff130..0d21c42fd 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts | |||
@@ -1,164 +1,163 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' |
2 | |||
3 | import { logger } from '../../helpers' | 2 | import { logger } from '../../helpers' |
3 | import { AccountModel } from '../account/account' | ||
4 | import { UserModel } from '../account/user' | ||
5 | import { OAuthClientModel } from './oauth-client' | ||
6 | |||
7 | export type OAuthTokenInfo = { | ||
8 | refreshToken: string | ||
9 | refreshTokenExpiresAt: Date, | ||
10 | client: { | ||
11 | id: number | ||
12 | }, | ||
13 | user: { | ||
14 | id: number | ||
15 | } | ||
16 | } | ||
4 | 17 | ||
5 | import { addMethodsToModel } from '../utils' | 18 | @Table({ |
6 | import { OAuthTokenAttributes, OAuthTokenInfo, OAuthTokenInstance, OAuthTokenMethods } from './oauth-token-interface' | 19 | tableName: 'oAuthToken', |
7 | 20 | indexes: [ | |
8 | let OAuthToken: Sequelize.Model<OAuthTokenInstance, OAuthTokenAttributes> | ||
9 | let getByRefreshTokenAndPopulateClient: OAuthTokenMethods.GetByRefreshTokenAndPopulateClient | ||
10 | let getByTokenAndPopulateUser: OAuthTokenMethods.GetByTokenAndPopulateUser | ||
11 | let getByRefreshTokenAndPopulateUser: OAuthTokenMethods.GetByRefreshTokenAndPopulateUser | ||
12 | |||
13 | export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { | ||
14 | OAuthToken = sequelize.define<OAuthTokenInstance, OAuthTokenAttributes>('OAuthToken', | ||
15 | { | 21 | { |
16 | accessToken: { | 22 | fields: [ 'refreshToken' ], |
17 | type: DataTypes.STRING, | 23 | unique: true |
18 | allowNull: false | ||
19 | }, | ||
20 | accessTokenExpiresAt: { | ||
21 | type: DataTypes.DATE, | ||
22 | allowNull: false | ||
23 | }, | ||
24 | refreshToken: { | ||
25 | type: DataTypes.STRING, | ||
26 | allowNull: false | ||
27 | }, | ||
28 | refreshTokenExpiresAt: { | ||
29 | type: DataTypes.DATE, | ||
30 | allowNull: false | ||
31 | } | ||
32 | }, | 24 | }, |
33 | { | 25 | { |
34 | indexes: [ | 26 | fields: [ 'accessToken' ], |
35 | { | 27 | unique: true |
36 | fields: [ 'refreshToken' ], | 28 | }, |
37 | unique: true | 29 | { |
38 | }, | 30 | fields: [ 'userId' ] |
39 | { | 31 | }, |
40 | fields: [ 'accessToken' ], | 32 | { |
41 | unique: true | 33 | fields: [ 'oAuthClientId' ] |
42 | }, | ||
43 | { | ||
44 | fields: [ 'userId' ] | ||
45 | }, | ||
46 | { | ||
47 | fields: [ 'oAuthClientId' ] | ||
48 | } | ||
49 | ] | ||
50 | } | 34 | } |
51 | ) | 35 | ] |
36 | }) | ||
37 | export class OAuthTokenModel extends Model<OAuthTokenModel> { | ||
52 | 38 | ||
53 | const classMethods = [ | 39 | @AllowNull(false) |
54 | associate, | 40 | @Column |
41 | accessToken: string | ||
55 | 42 | ||
56 | getByRefreshTokenAndPopulateClient, | 43 | @AllowNull(false) |
57 | getByTokenAndPopulateUser, | 44 | @Column |
58 | getByRefreshTokenAndPopulateUser | 45 | accessTokenExpiresAt: Date |
59 | ] | ||
60 | addMethodsToModel(OAuthToken, classMethods) | ||
61 | 46 | ||
62 | return OAuthToken | 47 | @AllowNull(false) |
63 | } | 48 | @Column |
49 | refreshToken: string | ||
64 | 50 | ||
65 | // --------------------------------------------------------------------------- | 51 | @AllowNull(false) |
52 | @Column | ||
53 | refreshTokenExpiresAt: Date | ||
66 | 54 | ||
67 | function associate (models) { | 55 | @CreatedAt |
68 | OAuthToken.belongsTo(models.User, { | 56 | createdAt: Date |
57 | |||
58 | @UpdatedAt | ||
59 | updatedAt: Date | ||
60 | |||
61 | @ForeignKey(() => UserModel) | ||
62 | @Column | ||
63 | userId: number | ||
64 | |||
65 | @BelongsTo(() => UserModel, { | ||
69 | foreignKey: { | 66 | foreignKey: { |
70 | name: 'userId', | ||
71 | allowNull: false | 67 | allowNull: false |
72 | }, | 68 | }, |
73 | onDelete: 'cascade' | 69 | onDelete: 'cascade' |
74 | }) | 70 | }) |
71 | User: UserModel | ||
75 | 72 | ||
76 | OAuthToken.belongsTo(models.OAuthClient, { | 73 | @ForeignKey(() => OAuthClientModel) |
74 | @Column | ||
75 | oAuthClientId: number | ||
76 | |||
77 | @BelongsTo(() => OAuthClientModel, { | ||
77 | foreignKey: { | 78 | foreignKey: { |
78 | name: 'oAuthClientId', | ||
79 | allowNull: false | 79 | allowNull: false |
80 | }, | 80 | }, |
81 | onDelete: 'cascade' | 81 | onDelete: 'cascade' |
82 | }) | 82 | }) |
83 | } | 83 | OAuthClients: OAuthClientModel[] |
84 | 84 | ||
85 | getByRefreshTokenAndPopulateClient = function (refreshToken: string) { | 85 | static getByRefreshTokenAndPopulateClient (refreshToken: string) { |
86 | const query = { | 86 | const query = { |
87 | where: { | 87 | where: { |
88 | refreshToken: refreshToken | 88 | refreshToken: refreshToken |
89 | }, | 89 | }, |
90 | include: [ OAuthToken['sequelize'].models.OAuthClient ] | 90 | include: [ OAuthClientModel ] |
91 | } | ||
92 | |||
93 | return OAuthTokenModel.findOne(query) | ||
94 | .then(token => { | ||
95 | if (!token) return null | ||
96 | |||
97 | return { | ||
98 | refreshToken: token.refreshToken, | ||
99 | refreshTokenExpiresAt: token.refreshTokenExpiresAt, | ||
100 | client: { | ||
101 | id: token.oAuthClientId | ||
102 | }, | ||
103 | user: { | ||
104 | id: token.userId | ||
105 | } | ||
106 | } as OAuthTokenInfo | ||
107 | }) | ||
108 | .catch(err => { | ||
109 | logger.info('getRefreshToken error.', err) | ||
110 | throw err | ||
111 | }) | ||
91 | } | 112 | } |
92 | 113 | ||
93 | return OAuthToken.findOne(query) | 114 | static getByTokenAndPopulateUser (bearerToken: string) { |
94 | .then(token => { | 115 | const query = { |
95 | if (!token) return null | 116 | where: { |
96 | 117 | accessToken: bearerToken | |
97 | const tokenInfos: OAuthTokenInfo = { | 118 | }, |
98 | refreshToken: token.refreshToken, | 119 | include: [ |
99 | refreshTokenExpiresAt: token.refreshTokenExpiresAt, | 120 | { |
100 | client: { | 121 | model: UserModel, |
101 | id: token.oAuthClientId | 122 | include: [ |
102 | }, | 123 | { |
103 | user: { | 124 | model: AccountModel, |
104 | id: token.userId | 125 | required: true |
126 | } | ||
127 | ] | ||
105 | } | 128 | } |
106 | } | 129 | ] |
130 | } | ||
107 | 131 | ||
108 | return tokenInfos | 132 | return OAuthTokenModel.findOne(query).then(token => { |
109 | }) | 133 | if (token) token['user'] = token.User |
110 | .catch(err => { | ||
111 | logger.info('getRefreshToken error.', err) | ||
112 | throw err | ||
113 | }) | ||
114 | } | ||
115 | 134 | ||
116 | getByTokenAndPopulateUser = function (bearerToken: string) { | 135 | return token |
117 | const query = { | 136 | }) |
118 | where: { | ||
119 | accessToken: bearerToken | ||
120 | }, | ||
121 | include: [ | ||
122 | { | ||
123 | model: OAuthToken['sequelize'].models.User, | ||
124 | include: [ | ||
125 | { | ||
126 | model: OAuthToken['sequelize'].models.Account, | ||
127 | required: true | ||
128 | } | ||
129 | ] | ||
130 | } | ||
131 | ] | ||
132 | } | 137 | } |
133 | 138 | ||
134 | return OAuthToken.findOne(query).then(token => { | 139 | static getByRefreshTokenAndPopulateUser (refreshToken: string) { |
135 | if (token) token['user'] = token.User | 140 | const query = { |
141 | where: { | ||
142 | refreshToken: refreshToken | ||
143 | }, | ||
144 | include: [ | ||
145 | { | ||
146 | model: UserModel, | ||
147 | include: [ | ||
148 | { | ||
149 | model: AccountModel, | ||
150 | required: true | ||
151 | } | ||
152 | ] | ||
153 | } | ||
154 | ] | ||
155 | } | ||
136 | 156 | ||
137 | return token | 157 | return OAuthTokenModel.findOne(query).then(token => { |
138 | }) | 158 | token['user'] = token.User |
139 | } | ||
140 | 159 | ||
141 | getByRefreshTokenAndPopulateUser = function (refreshToken: string) { | 160 | return token |
142 | const query = { | 161 | }) |
143 | where: { | ||
144 | refreshToken: refreshToken | ||
145 | }, | ||
146 | include: [ | ||
147 | { | ||
148 | model: OAuthToken['sequelize'].models.User, | ||
149 | include: [ | ||
150 | { | ||
151 | model: OAuthToken['sequelize'].models.Account, | ||
152 | required: true | ||
153 | } | ||
154 | ] | ||
155 | } | ||
156 | ] | ||
157 | } | 162 | } |
158 | |||
159 | return OAuthToken.findOne(query).then(token => { | ||
160 | token['user'] = token.User | ||
161 | |||
162 | return token | ||
163 | }) | ||
164 | } | 163 | } |