@or-sdk/authorizer 0.25.0-beta.990.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +317 -0
  2. package/README.md +12 -32
  3. package/dist/cjs/Basic/BasicCollection.js +166 -26
  4. package/dist/cjs/Basic/BasicCollection.js.map +1 -1
  5. package/dist/cjs/Basic/utils/createAuthKey.js +4 -0
  6. package/dist/cjs/Basic/utils/createAuthKey.js.map +1 -1
  7. package/dist/cjs/OAuth/OAuth.js +92 -138
  8. package/dist/cjs/OAuth/OAuth.js.map +1 -1
  9. package/dist/cjs/OAuth/index.js +1 -3
  10. package/dist/cjs/OAuth/index.js.map +1 -1
  11. package/dist/cjs/OAuth/types.js +1 -1
  12. package/dist/cjs/OAuth/types.js.map +1 -1
  13. package/dist/cjs/OAuth/utils/ServiceDefinition.js.map +1 -1
  14. package/dist/cjs/OAuth/utils/createAuthKey.js +4 -0
  15. package/dist/cjs/OAuth/utils/createAuthKey.js.map +1 -1
  16. package/dist/cjs/OAuth/utils/createOAuthHelper.js +379 -0
  17. package/dist/cjs/OAuth/utils/createOAuthHelper.js.map +1 -0
  18. package/dist/cjs/OAuth/utils/formatScope.js.map +1 -1
  19. package/dist/cjs/{OAuth → OAuthCollection}/OAuthCollection.js +132 -28
  20. package/dist/cjs/OAuthCollection/OAuthCollection.js.map +1 -0
  21. package/dist/cjs/OAuthCollection/index.js +21 -0
  22. package/dist/cjs/OAuthCollection/index.js.map +1 -0
  23. package/dist/cjs/Token/TokenCollection.js +166 -21
  24. package/dist/cjs/Token/TokenCollection.js.map +1 -1
  25. package/dist/cjs/Token/utils/createAuthKey.js +4 -0
  26. package/dist/cjs/Token/utils/createAuthKey.js.map +1 -1
  27. package/dist/cjs/constants.js +3 -2
  28. package/dist/cjs/constants.js.map +1 -1
  29. package/dist/cjs/index.js +2 -1
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/esm/Basic/BasicCollection.js +115 -17
  32. package/dist/esm/Basic/BasicCollection.js.map +1 -1
  33. package/dist/esm/Basic/utils/createAuthKey.js +3 -0
  34. package/dist/esm/Basic/utils/createAuthKey.js.map +1 -1
  35. package/dist/esm/OAuth/OAuth.js +56 -115
  36. package/dist/esm/OAuth/OAuth.js.map +1 -1
  37. package/dist/esm/OAuth/index.js +0 -1
  38. package/dist/esm/OAuth/index.js.map +1 -1
  39. package/dist/esm/OAuth/types.js.map +1 -1
  40. package/dist/esm/OAuth/utils/ServiceDefinition.js.map +1 -1
  41. package/dist/esm/OAuth/utils/createAuthKey.js +3 -0
  42. package/dist/esm/OAuth/utils/createAuthKey.js.map +1 -1
  43. package/dist/esm/OAuth/utils/createOAuthHelper.js +262 -0
  44. package/dist/esm/OAuth/utils/createOAuthHelper.js.map +1 -0
  45. package/dist/esm/OAuth/utils/formatScope.js.map +1 -1
  46. package/dist/esm/OAuthCollection/OAuthCollection.js +190 -0
  47. package/dist/esm/OAuthCollection/OAuthCollection.js.map +1 -0
  48. package/dist/esm/OAuthCollection/index.js +3 -0
  49. package/dist/esm/OAuthCollection/index.js.map +1 -0
  50. package/dist/esm/Token/TokenCollection.js +115 -12
  51. package/dist/esm/Token/TokenCollection.js.map +1 -1
  52. package/dist/esm/Token/utils/createAuthKey.js +3 -0
  53. package/dist/esm/Token/utils/createAuthKey.js.map +1 -1
  54. package/dist/esm/constants.js +1 -0
  55. package/dist/esm/constants.js.map +1 -1
  56. package/dist/esm/index.js +2 -1
  57. package/dist/esm/index.js.map +1 -1
  58. package/dist/types/Basic/BasicCollection.d.ts +6 -4
  59. package/dist/types/Basic/BasicCollection.d.ts.map +1 -1
  60. package/dist/types/Basic/types.d.ts +20 -11
  61. package/dist/types/Basic/types.d.ts.map +1 -1
  62. package/dist/types/Basic/utils/createAuthKey.d.ts +1 -0
  63. package/dist/types/Basic/utils/createAuthKey.d.ts.map +1 -1
  64. package/dist/types/OAuth/OAuth.d.ts +8 -5
  65. package/dist/types/OAuth/OAuth.d.ts.map +1 -1
  66. package/dist/types/OAuth/index.d.ts +0 -1
  67. package/dist/types/OAuth/index.d.ts.map +1 -1
  68. package/dist/types/OAuth/types.d.ts +95 -19
  69. package/dist/types/OAuth/types.d.ts.map +1 -1
  70. package/dist/types/OAuth/utils/createAuthKey.d.ts +1 -0
  71. package/dist/types/OAuth/utils/createAuthKey.d.ts.map +1 -1
  72. package/dist/types/OAuth/utils/createOAuthHelper.d.ts +33 -0
  73. package/dist/types/OAuth/utils/createOAuthHelper.d.ts.map +1 -0
  74. package/dist/types/OAuthCollection/OAuthCollection.d.ts +27 -0
  75. package/dist/types/OAuthCollection/OAuthCollection.d.ts.map +1 -0
  76. package/dist/types/OAuthCollection/index.d.ts +3 -0
  77. package/dist/types/OAuthCollection/index.d.ts.map +1 -0
  78. package/dist/types/Token/TokenCollection.d.ts +5 -2
  79. package/dist/types/Token/TokenCollection.d.ts.map +1 -1
  80. package/dist/types/Token/types.d.ts +19 -5
  81. package/dist/types/Token/types.d.ts.map +1 -1
  82. package/dist/types/Token/utils/createAuthKey.d.ts +1 -0
  83. package/dist/types/Token/utils/createAuthKey.d.ts.map +1 -1
  84. package/dist/types/constants.d.ts +1 -0
  85. package/dist/types/constants.d.ts.map +1 -1
  86. package/dist/types/index.d.ts +2 -1
  87. package/dist/types/index.d.ts.map +1 -1
  88. package/package.json +32 -26
  89. package/src/Basic/BasicCollection.ts +170 -18
  90. package/src/Basic/types.ts +17 -14
  91. package/src/Basic/utils/createAuthKey.ts +4 -0
  92. package/src/OAuth/OAuth.ts +111 -195
  93. package/src/OAuth/index.ts +0 -1
  94. package/src/OAuth/types.ts +171 -15
  95. package/src/OAuth/utils/createAuthKey.ts +8 -0
  96. package/src/OAuth/utils/createOAuthHelper.ts +374 -0
  97. package/src/OAuthCollection/OAuthCollection.ts +348 -0
  98. package/src/OAuthCollection/index.ts +3 -0
  99. package/src/Token/TokenCollection.ts +174 -16
  100. package/src/Token/types.ts +15 -0
  101. package/src/Token/utils/createAuthKey.ts +4 -0
  102. package/src/constants.ts +1 -0
  103. package/src/index.ts +2 -1
  104. package/dist/cjs/OAuth/OAuthCollection.js.map +0 -1
  105. package/dist/esm/OAuth/OAuthCollection.js +0 -120
  106. package/dist/esm/OAuth/OAuthCollection.js.map +0 -1
  107. package/dist/types/OAuth/OAuthCollection.d.ts +0 -21
  108. package/dist/types/OAuth/OAuthCollection.d.ts.map +0 -1
  109. package/src/OAuth/OAuthCollection.ts +0 -206
@@ -0,0 +1,374 @@
1
+ import { KeyValueStorage } from '@or-sdk/key-value-storage';
2
+ import { Providers } from '@or-sdk/providers';
3
+ import { EVENT_MANAGER_SERVICE_KEY } from '@or-sdk/event-manager';
4
+ import { Discovery } from '@or-sdk/discovery';
5
+
6
+ import { v4 as uuidv4 } from 'uuid';
7
+
8
+ import {
9
+ OAuthApp,
10
+ CreateOAuthConfig,
11
+ ServiceDefinitionConfig,
12
+ OAuthDynamicCollection,
13
+ LocalService,
14
+ } from './../types';
15
+
16
+ import {
17
+ SERVICE_PROVIDER_PATH,
18
+ OAUTH_REDIRECT_PROVIDER_PATH,
19
+ NEXT_OAUTH_REDIRECT_PROVIDER_PATH,
20
+ PREDEFINED_APP,
21
+ TEMPORARY_DATA_EXPIRATION_TIME,
22
+ } from './../../constants';
23
+
24
+ import { formatScope } from './../utils/formatScope';
25
+ import { ServiceDefinition } from './../utils/ServiceDefinition';
26
+ import { createAuthKey, createDynamicKey } from './../utils/createAuthKey';
27
+
28
+ export default class OAuthCreator {
29
+ private params: CreateOAuthConfig;
30
+ private app: OAuthApp | undefined;
31
+ private authKey = '';
32
+ private service: ServiceDefinition | undefined;
33
+ private readonly keyValueStorage: KeyValueStorage;
34
+ private readonly providers: Providers;
35
+
36
+ constructor(params: CreateOAuthConfig) {
37
+ this.params = params;
38
+
39
+ this.validateInput();
40
+
41
+ this.keyValueStorage = new KeyValueStorage({
42
+ accountId: params.crossAccount ? params.accountId : undefined,
43
+ sdkUrl: params.sdkUrl,
44
+ token: params.token,
45
+ });
46
+
47
+ this.providers = new Providers({
48
+ token: params.token,
49
+ eventManagerUrl: params.eventManagerUrl,
50
+ providersAccountId: params.providersAccountId,
51
+ });
52
+ }
53
+
54
+ public async getOAuthParams() {
55
+ if (this.params.authKey) {
56
+ await this.resolveReauthParams();
57
+ }
58
+
59
+ await this.resolveDiscoveryParams();
60
+
61
+ const res = await this.getAppAndService();
62
+
63
+ this.service = res.serviceDefinition;
64
+ this.app = res.currentApp;
65
+
66
+
67
+ this.getAuthKey();
68
+
69
+ const { redirectProviderUrl, redirectPath } = await this.saveTempData();
70
+
71
+ const authorizeUrl = this.formAuthUrl(redirectPath, redirectProviderUrl);
72
+
73
+ if (this.params.dynamicCollection) {
74
+ this.saveToDynamicCollection;
75
+ }
76
+
77
+ return {
78
+ oAuthParams: {
79
+ accountId: this.params.crossAccount ? this.params.accountId : undefined,
80
+ authKey: this.params.useNextProvider ? ('::' + this.authKey.split('::').slice(1, 3).join('::')) : this.authKey,
81
+ authName: this.params.authName,
82
+ discoveryUrl: this.params.discoveryUrl,
83
+ dynamicCollection: this.params.dynamicCollection,
84
+ eventManagerUrl: this.params.eventManagerUrl,
85
+ providersAccountId: this.params.providersAccountId,
86
+ serviceName: this.params.serviceName,
87
+ token: this.params.token,
88
+ },
89
+ authorizeUrl,
90
+ };
91
+ }
92
+
93
+ private validateInput() {
94
+ const {
95
+ accountId,
96
+ crossAccount = true,
97
+ destinationAccount = 'CURRENT',
98
+ eventManagerUrl,
99
+ providersAccountId,
100
+ sdkUrl,
101
+ } = this.params;
102
+
103
+ if (!this.params.authKey) {
104
+ if (!this.params.appId) {
105
+ throw new Error('Application ID is missing');
106
+ } else if (!this.params.authName) {
107
+ throw new Error('Authorization name is missing');
108
+ }
109
+ }
110
+
111
+ if (!this.params.serviceName) {
112
+ throw new Error('Service name is missing');
113
+ } else if (!this.params.token) {
114
+ throw new Error('Authorization token is missing');
115
+ }
116
+
117
+ if (!sdkUrl || !eventManagerUrl || !providersAccountId || !accountId) {
118
+ if (!this.params.discoveryUrl) {
119
+ throw new Error('Discovery URL is missing.');
120
+ }
121
+ }
122
+
123
+ this.params.destinationAccount = destinationAccount;
124
+ this.params.crossAccount = crossAccount;
125
+ this.params.keyValueCollection =
126
+ this.params.keyValueCollection || this.params.serviceName;
127
+ }
128
+
129
+ private async resolveDiscoveryParams() {
130
+ const { accountId, eventManagerUrl, providersAccountId } = this.params;
131
+ if (accountId && eventManagerUrl && providersAccountId) {
132
+ return;
133
+ }
134
+
135
+ const discovery = new Discovery({
136
+ token: this.params.token,
137
+ discoveryUrl: this.params.discoveryUrl,
138
+ });
139
+
140
+ if (!accountId) {
141
+ this.params.accountId = await discovery.getCurrentAccountId().catch(() => {
142
+ throw new Error('Could not request current account ID');
143
+ });
144
+ }
145
+
146
+ if (!eventManagerUrl) {
147
+ this.params.eventManagerUrl = await discovery.getServiceUrl(EVENT_MANAGER_SERVICE_KEY).catch(() => {
148
+ throw new Error('Could not request current Event Manager URL');
149
+ });
150
+ }
151
+
152
+ if (!providersAccountId) {
153
+ this.params.providersAccountId = await discovery.getProvidersAccountId().catch(() => {
154
+ throw new Error('Could not request provider`s account ID');
155
+ });
156
+ }
157
+ }
158
+
159
+ private async getAppAndService() {
160
+
161
+ const services = await this.providers.makeRequest<{
162
+ [key: string]: ServiceDefinitionConfig;
163
+ }>({
164
+ method: 'GET',
165
+ route: SERVICE_PROVIDER_PATH,
166
+ params: {
167
+ type: 'list',
168
+ },
169
+ }).catch(() => { throw new Error('Could not request services list'); });
170
+
171
+ const localServices = await this.keyValueStorage.listKeys(
172
+ '__authorization_service_predefined_services_local',
173
+ undefined,
174
+ true
175
+ ) as unknown as Record<string, LocalService[]>;
176
+
177
+ localServices.items.forEach(el => (services[el.key] = el.value));
178
+
179
+ const currentServiceData = services[this.params.serviceName];
180
+ if (!currentServiceData) {
181
+ throw new Error('Service name is incorrect');
182
+ }
183
+
184
+ const apps = await this.keyValueStorage.getValueByKey(
185
+ this.params.keyValueCollection as string,
186
+ '__authorizer_apps'
187
+ );
188
+
189
+ if (!apps || !apps.value) {
190
+ throw new Error('Apps are missing in service collection');
191
+ }
192
+
193
+ // eslint-disable-next-line
194
+ const currentApp = (apps.value as any).find(
195
+ (app: { label: string; value: OAuthApp; }) => app.value.appId === this.params.appId
196
+ ).value;
197
+
198
+ return {
199
+ currentApp,
200
+ serviceDefinition: new ServiceDefinition(
201
+ currentServiceData,
202
+ currentApp.authLinkParams,
203
+ currentApp.environment
204
+ ),
205
+ };
206
+ }
207
+
208
+ private async resolveReauthParams() {
209
+ const old_auth_record = await this.keyValueStorage.getValueByKey(
210
+ this.params.keyValueCollection as string,
211
+ this.params.authKey as string
212
+ );
213
+
214
+ const old_auth: Record<string, string> = old_auth_record.value as unknown as Record<string, string>;
215
+
216
+ if (!old_auth) {
217
+ throw new Error('Could not reauthorize non-existing authorization');
218
+ }
219
+
220
+ if (old_auth.isRemote) {
221
+ throw new Error('Reauthorization of remote authorizations is not implemented.');
222
+ }
223
+
224
+ this.params.appId = old_auth.appId;
225
+ this.params.scope = old_auth.scope as unknown as string[];
226
+ this.params.authName = old_auth.authName;
227
+ }
228
+
229
+ private getAuthKey() {
230
+ const id = uuidv4();
231
+
232
+ if (this.params.authKey) {
233
+ if (this.params.authKey[0] === ':') {
234
+ this.params.useNextProvider = true;
235
+ this.authKey = id + this.params.authKey;
236
+
237
+ } else {
238
+ this.params.useNextProvider = false;
239
+ this.authKey = this.params.authKey;
240
+ }
241
+
242
+ } else {
243
+ const keyAccountId = this.params.destinationAccount === 'CURRENT' ? this.params.accountId :
244
+ this.params.destinationAccount === 'PROVIDER' ? this.params.providersAccountId :
245
+ this.params.destinationAccount === 'CUSTOM' ? this.params.customAccountId : null;
246
+
247
+ this.authKey = this.params.dynamicCollection ?
248
+ createDynamicKey(id, this.params.dynamicCollection, this.params.serviceName, keyAccountId || null) :
249
+ createAuthKey(id, this.params.authName, this.params.keyValueCollection as string, keyAccountId || null);
250
+
251
+ }
252
+ }
253
+
254
+ private async saveTempData() {
255
+ const redirectPath = this.params.useNextProvider ? NEXT_OAUTH_REDIRECT_PROVIDER_PATH : OAUTH_REDIRECT_PROVIDER_PATH;
256
+ const redirectProviderUrl = `${this.params.eventManagerUrl}/http/${this.params.providersAccountId}${redirectPath}`;
257
+ const serviceDefinition = this.service as ServiceDefinition;
258
+
259
+ // eslint-disable-next-line
260
+ const authConfigs: any = {
261
+ ...(this.params.additionalBodyData || {}),
262
+ grant_type: 'authorization_code',
263
+ redirect_uri: redirectProviderUrl,
264
+ appId: this.params.appId,
265
+ };
266
+
267
+ if (this.params.scope) {
268
+ authConfigs.scope = this.params.authKey ?
269
+ this.params.scope :
270
+ formatScope(this.params.scope, serviceDefinition.scopeType);
271
+ }
272
+
273
+ const configs = {
274
+ [serviceDefinition.requestDataType]: authConfigs,
275
+ };
276
+
277
+ const tempAuthData = {
278
+ accountId: this.params.accountId,
279
+ additionalHeaders: this.params.additionalHeaders || {},
280
+ configs,
281
+ displayServiceName: serviceDefinition.displayServiceName,
282
+ expiresInDefaultValue: serviceDefinition.expiresInDefaultValue,
283
+ isCustomApp: this.params.appId !== PREDEFINED_APP,
284
+ name: this.params.authName,
285
+ refreshUri: serviceDefinition.refreshUri,
286
+ requestDataType: serviceDefinition.requestDataType,
287
+ service: this.params.keyValueCollection,
288
+ serviceConfigName: this.params.serviceName,
289
+ storeAccount: this.params.destinationAccount,
290
+ storeCustomAccountId: this.params.destinationAccount === 'CUSTOM' ? this.params.customAccountId : undefined,
291
+ urlToExchangeToken: serviceDefinition.exchangeTokenUri,
292
+ };
293
+
294
+ const authDataExpire = Date.now() + TEMPORARY_DATA_EXPIRATION_TIME;
295
+ await this.keyValueStorage.setValueByKey(
296
+ '__authorizer_temp-uuid',
297
+ this.authKey.split('::')[0],
298
+ tempAuthData,
299
+ authDataExpire
300
+ );
301
+ return {
302
+ redirectPath,
303
+ redirectProviderUrl,
304
+ };
305
+ }
306
+
307
+ private formAuthUrl(redirectPath: string, redirectProviderUrl: string) {
308
+ const serviceDefinition = this.service as ServiceDefinition;
309
+ const currentApp = this.app as OAuthApp;
310
+
311
+ const authUrl = new URL(serviceDefinition.authorizeUri);
312
+ const additionalParams: { [key: string]: string; } = JSON.parse(
313
+ serviceDefinition.authRequestAdditionalParams
314
+ );
315
+
316
+ Object.entries(additionalParams.queryParams).forEach(([key, value]) => {
317
+ authUrl.searchParams.append(key, value);
318
+ });
319
+ authUrl.searchParams.append('response_type', 'code');
320
+ authUrl.searchParams.append('client_id', currentApp.clientId);
321
+ authUrl.searchParams.append('redirect_uri', redirectProviderUrl);
322
+ authUrl.searchParams.append('state', this.authKey);
323
+
324
+ if (this.params.scope) {
325
+
326
+ authUrl.searchParams.append(
327
+ 'scope',
328
+ this.params.authKey ?
329
+ this.params.scope as unknown as string :
330
+ formatScope(this.params.scope, serviceDefinition.scopeType)
331
+ );
332
+ }
333
+
334
+ if (this.params.userScope) {
335
+ authUrl.searchParams.append('user_scope', this.params.userScope);
336
+ }
337
+
338
+ if (this.params.useNonce) {
339
+ authUrl.searchParams.append('nonce', uuidv4());
340
+ }
341
+
342
+ return authUrl.href;
343
+ }
344
+
345
+ private async saveToDynamicCollection() {
346
+ const { value } = await this.keyValueStorage.getValueByKey(
347
+ '__authorizer_dynamic_collections',
348
+ this.params.dynamicCollection as string
349
+ );
350
+
351
+ const collection = (value || {
352
+ name: this.params.dynamicCollection,
353
+ type: 'oauth',
354
+ service: this.params.serviceName,
355
+ serviceConfigName: this.params.serviceName,
356
+ authorizations: {},
357
+ }) as OAuthDynamicCollection;
358
+
359
+ if (collection.authorizations[this.params.authName]) {
360
+ await this.keyValueStorage.deleteKey(
361
+ this.params.serviceName,
362
+ collection.authorizations[this.params.authName]
363
+ );
364
+ }
365
+
366
+ collection.authorizations[this.params.authName] = this.authKey;
367
+
368
+ await this.keyValueStorage.setValueByKey(
369
+ '__authorizer_dynamic_collections',
370
+ this.params.dynamicCollection as string,
371
+ collection
372
+ );
373
+ }
374
+ }