skapi-js 1.2.14-beta.3 → 1.2.14-beta.6

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 (92) hide show
  1. package/dist/bundle-report-commonjs.html +2 -2
  2. package/dist/bundle-report-esm.html +2 -2
  3. package/dist/bundle-report-node-esm.html +2 -2
  4. package/dist/bundle-report.html +2 -2
  5. package/dist/skapi.cjs +1 -1
  6. package/dist/skapi.cjs.map +1 -1
  7. package/dist/skapi.js +1 -1
  8. package/dist/skapi.js.map +1 -1
  9. package/dist/skapi.mjs +1 -1
  10. package/dist/skapi.mjs.map +1 -1
  11. package/dist/skapi.node.mjs +1 -1
  12. package/dist/skapi.node.mjs.map +1 -1
  13. package/js/package.json +6 -5
  14. package/js/src/Types.d.ts +40 -2
  15. package/js/src/main/skapi.d.ts +41 -29
  16. package/js/src/main/skapi.js +48 -60
  17. package/js/src/main/skapi.js.map +1 -1
  18. package/js/src/methods/admin.d.ts +2 -4
  19. package/js/src/methods/database.d.ts +8 -0
  20. package/js/src/methods/database.js +285 -8
  21. package/js/src/methods/database.js.map +1 -1
  22. package/js/src/methods/param_restrictions.d.ts +8 -4
  23. package/js/src/methods/param_restrictions.js +72 -6
  24. package/js/src/methods/param_restrictions.js.map +1 -1
  25. package/js/src/methods/request.js +1 -1
  26. package/js/src/methods/request.js.map +1 -1
  27. package/js/src/methods/subscription.d.ts +0 -6
  28. package/js/src/methods/subscription.js +0 -28
  29. package/js/src/methods/subscription.js.map +1 -1
  30. package/js/src/methods/vivian.d.ts +18 -3
  31. package/js/src/methods/vivian.js +20 -10
  32. package/js/src/methods/vivian.js.map +1 -1
  33. package/js/src/utils/network.js +16 -11
  34. package/js/src/utils/network.js.map +1 -1
  35. package/js/src/utils/utils.d.ts +3 -1
  36. package/js/src/utils/utils.js +15 -3
  37. package/js/src/utils/utils.js.map +1 -1
  38. package/package.json +6 -5
  39. package/js/Main.d.ts +0 -6
  40. package/js/Main.js +0 -6
  41. package/js/Main.js.map +0 -1
  42. package/js/Types.d.ts +0 -305
  43. package/js/Types.js +0 -2
  44. package/js/Types.js.map +0 -1
  45. package/js/main/error.d.ts +0 -9
  46. package/js/main/error.js +0 -46
  47. package/js/main/error.js.map +0 -1
  48. package/js/main/skapi.d.ts +0 -443
  49. package/js/main/skapi.js +0 -853
  50. package/js/main/skapi.js.map +0 -1
  51. package/js/methods/admin.d.ts +0 -61
  52. package/js/methods/admin.js +0 -325
  53. package/js/methods/admin.js.map +0 -1
  54. package/js/methods/database.d.ts +0 -65
  55. package/js/methods/database.js +0 -947
  56. package/js/methods/database.js.map +0 -1
  57. package/js/methods/notification.d.ts +0 -21
  58. package/js/methods/notification.js +0 -81
  59. package/js/methods/notification.js.map +0 -1
  60. package/js/methods/param_restrictions.d.ts +0 -21
  61. package/js/methods/param_restrictions.js +0 -144
  62. package/js/methods/param_restrictions.js.map +0 -1
  63. package/js/methods/realtime.d.ts +0 -35
  64. package/js/methods/realtime.js +0 -408
  65. package/js/methods/realtime.js.map +0 -1
  66. package/js/methods/request.d.ts +0 -43
  67. package/js/methods/request.js +0 -132
  68. package/js/methods/request.js.map +0 -1
  69. package/js/methods/subscription.d.ts +0 -53
  70. package/js/methods/subscription.js +0 -337
  71. package/js/methods/subscription.js.map +0 -1
  72. package/js/methods/user.d.ts +0 -176
  73. package/js/methods/user.js +0 -1120
  74. package/js/methods/user.js.map +0 -1
  75. package/js/methods/vivian.d.ts +0 -3
  76. package/js/methods/vivian.js +0 -36
  77. package/js/methods/vivian.js.map +0 -1
  78. package/js/methods/webrtc.d.ts +0 -26
  79. package/js/methods/webrtc.js +0 -608
  80. package/js/methods/webrtc.js.map +0 -1
  81. package/js/polyfills/global.d.ts +0 -3
  82. package/js/polyfills/global.js +0 -235
  83. package/js/polyfills/global.js.map +0 -1
  84. package/js/utils/network.d.ts +0 -24
  85. package/js/utils/network.js +0 -707
  86. package/js/utils/network.js.map +0 -1
  87. package/js/utils/utils.d.ts +0 -40
  88. package/js/utils/utils.js +0 -651
  89. package/js/utils/utils.js.map +0 -1
  90. package/js/utils/validator.d.ts +0 -24
  91. package/js/utils/validator.js +0 -293
  92. package/js/utils/validator.js.map +0 -1
@@ -1,1120 +0,0 @@
1
- import SkapiError from '../main/error';
2
- import { CognitoUserAttribute, CognitoUser, AuthenticationDetails, CognitoUserSession, CognitoIdToken, CognitoAccessToken, CognitoRefreshToken } from 'amazon-cognito-identity-js';
3
- import validator from '../utils/validator';
4
- import { request } from '../utils/network';
5
- import { MD5, extractFormData, fromBase62, parseUserAttributes } from '../utils/utils';
6
- let cognitoUser = null;
7
- function map_ticket_obj(t) {
8
- let mapper = {
9
- "tkid": 'ticket_id',
10
- "cond": 'condition',
11
- "stmp": 'timestamp',
12
- "actn": 'action',
13
- "cnt": 'count',
14
- "ttl": 'time_to_live',
15
- 'plch': 'placeholder',
16
- 'hash': 'hash',
17
- 'desc': 'description',
18
- 'pmc': 'limit_per_user'
19
- };
20
- let new_obj = {};
21
- for (let k in t) {
22
- if (k === 'tkid') {
23
- let tkid = t[k].split('#');
24
- if (tkid.length === 1) {
25
- new_obj['ticket_id'] = tkid[0];
26
- continue;
27
- }
28
- new_obj['ticket_id'] = tkid[1];
29
- new_obj['consume_id'] = tkid[2];
30
- new_obj['user_id'] = tkid[3];
31
- let rand = tkid[2].slice(-4);
32
- new_obj["is_test"] = rand === ":CHK";
33
- if (!t.stmp) {
34
- let timestampStr = tkid[2].slice(0, -4);
35
- if (/^[0-9]+$/.test(timestampStr)) {
36
- new_obj['timestamp'] = parseInt(timestampStr, 10);
37
- }
38
- else {
39
- new_obj['timestamp'] = fromBase62(tkid[2].slice(0, -4));
40
- }
41
- }
42
- }
43
- else if (mapper[k]) {
44
- new_obj[mapper[k]] = t[k];
45
- }
46
- else {
47
- new_obj[k] = t[k];
48
- }
49
- }
50
- return new_obj;
51
- }
52
- export async function consumeTicket(params) {
53
- if (!params.ticket_id) {
54
- throw new SkapiError('Ticket ID is required.', { code: 'INVALID_PARAMETER' });
55
- }
56
- if (!params.method) {
57
- throw new SkapiError('Method is required. Should be either "GET" or "POST"', { code: 'INVALID_PARAMETER' });
58
- }
59
- let ticket_id = params.ticket_id;
60
- await this.__connection;
61
- let resp = await request.bind(this)(`https://${this.service.slice(0, 4)}.${this.customApiDomain}/auth/consume/${this.service}/${this.owner}/${ticket_id}`, params?.data || {}, { method: params.method, auth: !!params?.auth });
62
- return map_ticket_obj(resp);
63
- }
64
- export async function getTickets(params, fetchOptions) {
65
- await this.__connection;
66
- let tickets = await request.bind(this)('ticket', Object.assign({ exec: 'list' }, params || {}), { auth: true, fetchOptions });
67
- tickets.list = tickets.list.map(map_ticket_obj);
68
- return tickets;
69
- }
70
- export async function getConsumedTickets(params, fetchOptions) {
71
- await this.__connection;
72
- let tickets = await request.bind(this)('ticket', Object.assign({ exec: 'consumed' }, params || {}), { auth: true, fetchOptions });
73
- tickets.list = tickets.list.map(map_ticket_obj);
74
- return tickets;
75
- }
76
- export async function registerTicket(params) {
77
- return request.bind(this)('register-ticket', Object.assign({ exec: 'reg' }, params), { auth: true });
78
- }
79
- export async function unregisterTicket(params) {
80
- return request.bind(this)('register-ticket', Object.assign({ exec: 'unreg' }, params), { auth: true });
81
- }
82
- export async function getJwtToken() {
83
- await this.__connection;
84
- if (this.session) {
85
- const currentTime = Math.floor(Date.now() / 1000);
86
- const idToken = this.session.getIdToken();
87
- const idTokenExp = idToken.getExpiration();
88
- if (idTokenExp < currentTime) {
89
- this.log('request:requesting new token', null);
90
- try {
91
- await authentication.bind(this)().getSession({ refreshToken: true });
92
- this.log('request:received new tokens', {
93
- exp: this.session?.idToken?.payload?.exp,
94
- currentTime,
95
- expiresIn: idTokenExp - currentTime,
96
- token: this.session?.accessToken?.jwtToken,
97
- refreshToken: this.session?.refreshToken?.token
98
- });
99
- }
100
- catch (err) {
101
- this.log('request:new token error', err);
102
- throw new SkapiError('User login is required.', { code: 'INVALID_REQUEST' });
103
- }
104
- }
105
- else {
106
- this.log('request:tokens', {
107
- exp: this.session.idToken.payload.exp,
108
- currentTime,
109
- expiresIn: idTokenExp - currentTime,
110
- token: this.session.accessToken.jwtToken,
111
- refreshToken: this.session.refreshToken.token
112
- });
113
- }
114
- return this.session?.idToken?.jwtToken;
115
- }
116
- else {
117
- this.log('request:no session', null);
118
- _out.bind(this)();
119
- throw new SkapiError('User login is required.', { code: 'INVALID_REQUEST' });
120
- }
121
- }
122
- function refreshSession(session, cognitoUser) {
123
- return new Promise((res, rej) => {
124
- cognitoUser.refreshSession(session.getRefreshToken(), (refreshErr, refreshedSession) => {
125
- this.log('getSession:refreshSessionCallback', { refreshErr, refreshedSession });
126
- if (refreshErr) {
127
- _out.bind(this)();
128
- rej(refreshErr);
129
- }
130
- else if (refreshedSession.isValid()) {
131
- res(refreshedSession);
132
- }
133
- else {
134
- _out.bind(this)();
135
- rej(new SkapiError('Invalid session.', { code: 'INVALID_REQUEST' }));
136
- }
137
- });
138
- });
139
- }
140
- export function authentication() {
141
- if (!this.userPool)
142
- throw new SkapiError('User pool is missing', { code: 'INVALID_REQUEST' });
143
- const getUserProfile = () => {
144
- let attr = cognitoUser.getSignInUserSession().getIdToken().payload || null;
145
- let user = parseUserAttributes(attr);
146
- this.log('normalized user attribute', user);
147
- this.__user = user;
148
- return user;
149
- };
150
- const getSession = async (option) => new Promise((res, rej) => {
151
- this.log('getSession:option', option);
152
- let { refreshToken = false, skipUserUpdateEventTrigger = false } = option || {};
153
- if (refreshToken && skipUserUpdateEventTrigger) {
154
- skipUserUpdateEventTrigger = false;
155
- }
156
- cognitoUser = this.userPool.getCurrentUser();
157
- if (!cognitoUser) {
158
- this.log('getSession:cognitoUser', cognitoUser);
159
- _out.bind(this)();
160
- rej(null);
161
- return;
162
- }
163
- let respond = (s) => {
164
- let sessionAttribute = s.getIdToken().payload;
165
- this.log('getSession:respond:sessionAttribute', sessionAttribute);
166
- if (sessionAttribute['custom:service'] !== this.service) {
167
- this.log('getSession:respond', 'invalid service, signing out');
168
- _out.bind(this)();
169
- throw new SkapiError('Invalid session.', { code: 'INVALID_REQUEST' });
170
- }
171
- this.session = s;
172
- getUserProfile();
173
- if (!skipUserUpdateEventTrigger) {
174
- this._runOnUserUpdateListeners(this.user);
175
- }
176
- return this.session;
177
- };
178
- cognitoUser.getSession((err, session) => {
179
- this.log('getSession:getSessionCallback', { err, session });
180
- if (!session) {
181
- _out.bind(this)();
182
- rej(new SkapiError('Current session does not exist.', { code: 'INVALID_REQUEST' }));
183
- return;
184
- }
185
- if (err) {
186
- refreshSession.bind(this)(session, cognitoUser).then(r => res(respond(r))).catch(rej);
187
- return;
188
- }
189
- const currentTime = Math.floor(Date.now() / 1000);
190
- const idToken = session.getIdToken();
191
- const idTokenExp = idToken.getExpiration();
192
- const isExpired = idTokenExp < currentTime;
193
- this.log('getSession:currentTime', currentTime);
194
- this.log('getSession:idTokenExp', idTokenExp);
195
- this.log('getSession:isExpired', isExpired);
196
- this.log('getSession:existingBearerToken', this.bearerToken);
197
- this.bearerToken = idToken.getJwtToken();
198
- if (isExpired || refreshToken || !session.isValid()) {
199
- refreshSession.bind(this)(session, cognitoUser).then(r => res(respond(r))).catch(rej);
200
- }
201
- else {
202
- try {
203
- res(respond(session));
204
- }
205
- catch (err) {
206
- rej(err);
207
- }
208
- }
209
- });
210
- });
211
- const createCognitoUser = (un, raw) => {
212
- let username = raw ? un : un.includes(this.service + '-') ? un : this.service + '-' + MD5.hash(un);
213
- return {
214
- cognitoUser: new CognitoUser({
215
- Username: username,
216
- Pool: this.userPool
217
- }),
218
- cognitoUsername: username
219
- };
220
- };
221
- const authenticateUser = (email, password, raw = false, is_openid = false) => {
222
- return new Promise((res, rej) => {
223
- this.__request_signup_confirmation = null;
224
- this.__disabledAccount = null;
225
- let initUser = createCognitoUser(email, raw);
226
- let username = initUser.cognitoUsername;
227
- let authenticationDetails = new AuthenticationDetails({
228
- Username: username,
229
- Password: password
230
- });
231
- initUser.cognitoUser.authenticateUser(authenticationDetails, {
232
- newPasswordRequired: (userAttributes, requiredAttributes) => {
233
- this.__disabledAccount = null;
234
- this.__request_signup_confirmation = username;
235
- if (userAttributes['custom:signup_ticket'] === 'PASS' || userAttributes['custom:signup_ticket'] === 'MEMBER' || userAttributes['custom:signup_ticket'] === 'OIDPASS') {
236
- initUser.cognitoUser.completeNewPasswordChallenge(password, {}, {
237
- onSuccess: _ => {
238
- cognitoUser = initUser.cognitoUser;
239
- getSession().then(session => res(this.user));
240
- },
241
- onFailure: (err) => {
242
- rej(new SkapiError(err.message || 'Failed to authenticate user.', { code: err.code }));
243
- }
244
- });
245
- }
246
- else {
247
- rej(new SkapiError("User's signup confirmation is required.", { code: 'SIGNUP_CONFIRMATION_NEEDED' }));
248
- }
249
- },
250
- onSuccess: _ => getSession({ skipUserUpdateEventTrigger: true }).then(_ => {
251
- this.__disabledAccount = null;
252
- this._runOnLoginListeners(this.user);
253
- this._runOnUserUpdateListeners(this.user);
254
- res(this.user);
255
- }),
256
- onFailure: (err) => {
257
- let error = [err.message || 'Failed to authenticate user.', err?.code || 'INVALID_REQUEST'];
258
- if (err.code === "NotAuthorizedException") {
259
- if (err.message === "User is disabled.") {
260
- this.__disabledAccount = username;
261
- error = ['This account is disabled.', 'USER_IS_DISABLED'];
262
- }
263
- else {
264
- if (is_openid) {
265
- error = ['The account already exists.', 'ACCOUNT_EXISTS'];
266
- }
267
- else {
268
- error = ['Incorrect username or password.', 'INCORRECT_USERNAME_OR_PASSWORD'];
269
- }
270
- }
271
- }
272
- else if (err.code === "UserNotFoundException") {
273
- error = ['Incorrect username or password.', 'INCORRECT_USERNAME_OR_PASSWORD'];
274
- }
275
- else if (err.code === "UserNotConfirmedException") {
276
- this.__request_signup_confirmation = username;
277
- error = ["User's signup confirmation is required.", 'SIGNUP_CONFIRMATION_NEEDED'];
278
- }
279
- else if (err.code === "TooManyRequestsException" || err.code === "LimitExceededException") {
280
- error = ['Too many attempts. Please try again later.', 'REQUEST_EXCEED'];
281
- }
282
- let errCode = error[1];
283
- let errMsg = error[0];
284
- if (errMsg.startsWith('#')) {
285
- errMsg = errMsg.substring(1);
286
- let customErr = errMsg.split(':');
287
- errCode = customErr[0].trim();
288
- errMsg = customErr[1].trim();
289
- if (errCode === 'SIGNUP_CONFIRMATION_NEEDED') {
290
- this.__request_signup_confirmation = username;
291
- }
292
- }
293
- rej(new SkapiError(errMsg, { code: errCode, cause: err }));
294
- }
295
- });
296
- });
297
- };
298
- const signup = (username, password, attributes) => {
299
- return new Promise((res, rej) => {
300
- this.userPool.signUp(username, password, attributes, null, (err, result) => {
301
- if (err) {
302
- let error = [err?.message || 'Failed to signup.', err?.code || 'ERROR'];
303
- if (err.code === 'UsernameExistsException') {
304
- error = ['The account already exists.', 'EXISTS'];
305
- }
306
- else if (err.code === 'InvalidPasswordException') {
307
- error = ['Invalid password. Password must be at least 6 characters.', 'INVALID_PARAMETER'];
308
- }
309
- else if (err.code === 'InvalidParameterException') {
310
- error = [err.message || 'Invalid parameter.', 'INVALID_PARAMETER'];
311
- }
312
- else if (err.code === 'TooManyRequestsException' || err.code === 'LimitExceededException') {
313
- error = ['Too many attempts. Please try again later.', 'REQUEST_EXCEED'];
314
- }
315
- else if (err.code === 'CodeDeliveryFailureException') {
316
- error = ['Failed to deliver verification code.', 'CODE_DELIVERY_FAILURE'];
317
- }
318
- else if (err.code === 'UserLambdaValidationException') {
319
- error = [err.message || 'Signup validation failed.', 'INVALID_REQUEST'];
320
- }
321
- rej(new SkapiError(error[0], { code: error[1], cause: err }));
322
- return;
323
- }
324
- res(result);
325
- return;
326
- });
327
- });
328
- };
329
- return {
330
- getSession,
331
- authenticateUser,
332
- createCognitoUser,
333
- signup
334
- };
335
- }
336
- export async function getProfile(options) {
337
- await this.__authConnection;
338
- let refreshToken = options?.refreshToken || false;
339
- if (!refreshToken) {
340
- return this.user;
341
- }
342
- try {
343
- await authentication.bind(this)().getSession(Object.assign({ skipUserUpdateEventTrigger: !refreshToken, refreshToken }, options));
344
- return this.user;
345
- }
346
- catch (err) {
347
- return null;
348
- }
349
- }
350
- export async function openIdLogin(params) {
351
- await this.__connection;
352
- params = validator.Params(params, {
353
- token: 'string',
354
- id: 'string',
355
- merge: v => {
356
- if (v === undefined)
357
- return false;
358
- if (typeof v === 'string') {
359
- return [v];
360
- }
361
- if (Array.isArray(v)) {
362
- for (let item of v) {
363
- if (typeof item !== 'string') {
364
- throw new SkapiError('"merge" array items should be type: <string>.', { code: 'INVALID_PARAMETER' });
365
- }
366
- }
367
- }
368
- if (typeof v !== 'boolean' && !Array.isArray(v)) {
369
- throw new SkapiError('"merge" should be type: <boolean | string[]>.', { code: 'INVALID_PARAMETER' });
370
- }
371
- return v;
372
- }
373
- });
374
- let oplog = await request.bind(this)("openid-logger", params);
375
- let logger = oplog.logger.split('#');
376
- let username = this.service + '-' + logger[0];
377
- let password = logger[1];
378
- return { userProfile: await authentication.bind(this)().authenticateUser(username, password, true, true), openid: oplog.openid };
379
- }
380
- function decodeBase64Utf8(base64) {
381
- const root = typeof globalThis !== 'undefined' ? globalThis : undefined;
382
- if (root?.Buffer) {
383
- return root.Buffer.from(base64, 'base64').toString('utf8');
384
- }
385
- if (typeof atob === 'function') {
386
- const binary = atob(base64);
387
- const bytes = new Uint8Array(binary.length);
388
- for (let i = 0; i < binary.length; i++) {
389
- bytes[i] = binary.charCodeAt(i);
390
- }
391
- if (typeof TextDecoder !== 'undefined') {
392
- return new TextDecoder().decode(bytes);
393
- }
394
- return binary;
395
- }
396
- throw new Error('No base64 decoder available in this environment');
397
- }
398
- function getUserFromToken(accessToken) {
399
- const parts = accessToken.split('.');
400
- if (parts.length !== 3) {
401
- throw new Error('Invalid JWT format');
402
- }
403
- const payload = parts[1];
404
- const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
405
- const decoded = decodeBase64Utf8(base64);
406
- const userData = JSON.parse(decoded);
407
- return userData;
408
- }
409
- export async function loginWithToken(params) {
410
- await this.__authConnection;
411
- this.log('loginWithToken:params', params);
412
- params = validator.Params(params, {
413
- idToken: 'string',
414
- accessToken: 'string',
415
- refreshToken: 'string'
416
- }, ['idToken']);
417
- const idTokenPayload = getUserFromToken(params.idToken);
418
- this.log('loginWithToken:idTokenPayload', idTokenPayload);
419
- if (idTokenPayload['custom:service'] !== this.service) {
420
- throw new SkapiError('Token does not belong to this service.', { code: 'INVALID_REQUEST' });
421
- }
422
- const currentTime = Math.floor(Date.now() / 1000);
423
- if (idTokenPayload.exp && idTokenPayload.exp < currentTime) {
424
- throw new SkapiError('Token has expired.', { code: 'INVALID_REQUEST' });
425
- }
426
- this.__user = parseUserAttributes(idTokenPayload);
427
- this.session = null;
428
- if (params.accessToken && params.refreshToken) {
429
- try {
430
- this.session = new CognitoUserSession({
431
- IdToken: new CognitoIdToken({ IdToken: params.idToken }),
432
- AccessToken: new CognitoAccessToken({ AccessToken: params.accessToken }),
433
- RefreshToken: new CognitoRefreshToken({ RefreshToken: params.refreshToken })
434
- });
435
- this.log('loginWithToken:session', this.session);
436
- this.log('loginWithToken:CognitoUser', CognitoUser);
437
- this.log('loginWithToken:userPool', this.userPool);
438
- if (CognitoUser && this.userPool) {
439
- this.log('loginWithToken:cognito:username', idTokenPayload['cognito:username']);
440
- let up = {
441
- Username: idTokenPayload['cognito:username'],
442
- Pool: this.userPool
443
- };
444
- this.log('loginWithToken:cognitoUserParams', up);
445
- cognitoUser = new CognitoUser(up);
446
- cognitoUser.setSignInUserSession(this.session);
447
- this.log('loginWithToken:cognitoUserRestored', {
448
- cognitoUserType: typeof cognitoUser,
449
- cognitoUserKeys: Object.keys(cognitoUser || {}),
450
- cognitoUser
451
- });
452
- }
453
- }
454
- catch (err) {
455
- this.log('loginWithToken:err', err);
456
- try {
457
- this.log('loginWithToken:err:stringified', JSON.stringify(err));
458
- }
459
- catch (e) {
460
- this.log('loginWithToken:err:stringifyFail', String(err));
461
- }
462
- try {
463
- const keys = Object.keys(err || {});
464
- const symbols = Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(err || {}) : [];
465
- const descriptors = Object.getOwnPropertyDescriptors ? Object.getOwnPropertyDescriptors(err || {}) : {};
466
- this.log('loginWithToken:createSessionError:allKeys', { keys, symbols, descriptors });
467
- }
468
- catch (e) {
469
- this.log('loginWithToken:createSessionError:allKeysFail', String(e));
470
- }
471
- }
472
- }
473
- this._runOnLoginListeners(this.user);
474
- this._runOnUserUpdateListeners(this.user);
475
- return this.user;
476
- }
477
- export async function checkAdmin() {
478
- await this.__connection;
479
- if (this.__user?.service === this.service) {
480
- return this.__user?.owner === this.host;
481
- }
482
- else {
483
- await logout.bind(this)();
484
- }
485
- return false;
486
- }
487
- export async function _out(global = false) {
488
- let toReturn = null;
489
- if (cognitoUser) {
490
- if (global) {
491
- toReturn = new Promise((res, rej) => {
492
- cognitoUser.globalSignOut({
493
- onSuccess: (result) => {
494
- this.log('globalSignOut:success', result);
495
- res(result);
496
- },
497
- onFailure: (err) => {
498
- this.log('globalSignOut:error', err);
499
- rej(err);
500
- }
501
- });
502
- });
503
- }
504
- else {
505
- cognitoUser.signOut();
506
- }
507
- }
508
- let to_be_erased = {
509
- 'session': null,
510
- '__startKeyHistory': {},
511
- '__cached_requests': {},
512
- '__user': null
513
- };
514
- if (toReturn) {
515
- toReturn = await toReturn;
516
- }
517
- for (let k in to_be_erased) {
518
- this[k] = to_be_erased[k];
519
- }
520
- this._runOnUserUpdateListeners(null);
521
- this._runOnLoginListeners(null);
522
- return toReturn;
523
- }
524
- export async function logout(params) {
525
- await this.__connection;
526
- let { data } = extractFormData(params);
527
- await _out.bind(this)(data?.global);
528
- return 'SUCCESS: The user has been logged out.';
529
- }
530
- export async function resendSignupConfirmation() {
531
- if (!this.__request_signup_confirmation) {
532
- throw new SkapiError('Least one login attempt is required.', { code: 'INVALID_REQUEST' });
533
- }
534
- let resend = await request.bind(this)("confirm-signup", {
535
- username: this.__request_signup_confirmation,
536
- });
537
- return resend;
538
- }
539
- export async function recoverAccount(redirect = false) {
540
- if (typeof redirect === 'string') {
541
- redirect = validator.Url(redirect);
542
- }
543
- else if (typeof redirect !== 'boolean') {
544
- throw new SkapiError('Argument should be type: <boolean | string>.', { code: 'INVALID_REQUEST' });
545
- }
546
- if (!this.__disabledAccount) {
547
- throw new SkapiError('Least one signin attempt of disabled account is required.', { code: 'INVALID_REQUEST' });
548
- }
549
- await request.bind(this)("recover-account", { username: this.__disabledAccount, redirect });
550
- return 'SUCCESS: Recovery e-mail has been sent.';
551
- }
552
- export async function login(form) {
553
- let params = validator.Params(form, {
554
- username: 'string',
555
- email: 'string',
556
- password: 'string'
557
- }, ['password']);
558
- await this.__authConnection;
559
- if (params.email) {
560
- try {
561
- validator.Email(params.email);
562
- }
563
- catch (err) {
564
- params.username = params.email;
565
- delete params.email;
566
- }
567
- }
568
- if (!params.username && !params.email) {
569
- throw new SkapiError('Least one of "username" or "email" is required.', { code: 'INVALID_PARAMETER' });
570
- }
571
- const resolved = await authentication.bind(this)().authenticateUser(params.username || params.email, params.password);
572
- return resolved;
573
- }
574
- export async function signup(form, option) {
575
- await this.__authConnection;
576
- let paramRestrictions = {
577
- username: 'string',
578
- password: (v) => validator.Password(v),
579
- email: (v) => validator.Email(v),
580
- name: 'string',
581
- address: (v) => {
582
- if (!v)
583
- return '';
584
- if (typeof v === 'string') {
585
- return v;
586
- }
587
- if (typeof v === 'object') {
588
- return JSON.stringify(v);
589
- }
590
- return undefined;
591
- },
592
- gender: 'string',
593
- birthdate: (v) => v ? validator.Birthdate(v) : "",
594
- phone_number: (v) => v ? validator.PhoneNumber(v) : "",
595
- email_public: ['boolean', () => false],
596
- address_public: ['boolean', () => false],
597
- gender_public: ['boolean', () => false],
598
- birthdate_public: ['boolean', () => false],
599
- phone_number_public: ['boolean', () => false],
600
- access_group: 'number',
601
- misc: 'string',
602
- picture: (v) => { if (v)
603
- return validator.Url(v);
604
- else
605
- return ""; },
606
- profile: (v) => { if (v)
607
- return validator.Url(v);
608
- else
609
- return ""; },
610
- family_name: 'string',
611
- given_name: 'string',
612
- middle_name: 'string',
613
- nickname: 'string',
614
- website: (v) => { if (v)
615
- return validator.Url(v);
616
- else
617
- return ""; },
618
- };
619
- let params = validator.Params(form || {}, paramRestrictions, ['email', 'password']);
620
- await logout.bind(this)();
621
- option = validator.Params(option || {}, {
622
- email_subscription: (v) => {
623
- if (typeof v !== 'boolean') {
624
- throw new SkapiError('"option.email_subscription" should be type: <boolean>.', { code: 'INVALID_PARAMETER' });
625
- }
626
- if (!option?.signup_confirmation) {
627
- throw new SkapiError('"option.signup_confirmation" is required for email subscription.', { code: 'INVALID_PARAMETER' });
628
- }
629
- return v;
630
- },
631
- signup_confirmation: (v) => {
632
- let value = v;
633
- if (typeof v === 'string') {
634
- value = validator.Url(v);
635
- }
636
- else if (typeof v === 'boolean') {
637
- value = v;
638
- }
639
- else {
640
- throw new SkapiError('"option.signup_confirmation" should be type: <string | boolean>.', { code: 'INVALID_PARAMETER' });
641
- }
642
- if (value && !params.email) {
643
- throw new SkapiError('"email" is required for signup confirmation.', { code: 'INVALID_PARAMETER' });
644
- }
645
- return value;
646
- },
647
- login: (v) => {
648
- if (typeof v === 'boolean') {
649
- if (option.signup_confirmation && v) {
650
- throw new SkapiError('"login" is not allowed when "option.signup_confirmation" is true.', { code: 'INVALID_PARAMETER' });
651
- }
652
- return v;
653
- }
654
- throw new SkapiError('"option.login" should be type: boolean.', { code: 'INVALID_PARAMETER' });
655
- }
656
- });
657
- let logUser = option?.login || false;
658
- params.signup_confirmation = option?.signup_confirmation || false;
659
- ;
660
- params.email_subscription = option?.email_subscription || false;
661
- if (params.email_public && !params.signup_confirmation) {
662
- throw new SkapiError('"option.signup_confirmation" should be true if "email_public" is set to true.', { code: 'INVALID_PARAMETER' });
663
- }
664
- params.service = this.service;
665
- params.owner = this.owner;
666
- let newUser = authentication.bind(this)().createCognitoUser(params.username || params.email);
667
- for (let k of ['email_public',
668
- 'address_public',
669
- 'gender_public',
670
- 'birthdate_public',
671
- 'phone_number_public']) {
672
- params[k] = params[k] ? '1' : '0';
673
- }
674
- if (params.access_group) {
675
- params.access_group = params.access_group.toString();
676
- }
677
- let signup_key = (await request.bind(this)('signupkey', {
678
- username: newUser.cognitoUsername,
679
- signup_confirmation: typeof params.signup_confirmation === 'boolean' ? JSON.stringify(params.signup_confirmation) : params.signup_confirmation,
680
- email_subscription: params.email_subscription,
681
- })).split(':');
682
- let signup_ticket = signup_key.slice(1).join(':');
683
- let attributeList = [
684
- new CognitoUserAttribute({
685
- Name: 'custom:signup',
686
- Value: signup_key[0]
687
- }),
688
- new CognitoUserAttribute({
689
- Name: 'locale',
690
- Value: signup_ticket.split('#')[1]
691
- }),
692
- new CognitoUserAttribute({
693
- Name: 'custom:signup_ticket',
694
- Value: signup_ticket
695
- })
696
- ];
697
- for (let k in paramRestrictions) {
698
- let customParams = [
699
- 'email_public',
700
- 'address_public',
701
- 'gender_public',
702
- 'birthdate_public',
703
- 'phone_number_public',
704
- 'misc',
705
- 'service',
706
- 'owner'
707
- ];
708
- if (params[k] === "") {
709
- continue;
710
- }
711
- if (k === 'username' || k === 'password' || k === 'access_group') {
712
- continue;
713
- }
714
- if (customParams.includes(k)) {
715
- attributeList.push(new CognitoUserAttribute({
716
- Name: 'custom:' + k,
717
- Value: params[k]
718
- }));
719
- }
720
- else {
721
- attributeList.push(new CognitoUserAttribute({
722
- Name: k,
723
- Value: params[k]
724
- }));
725
- }
726
- }
727
- await authentication.bind(this)().signup(newUser.cognitoUsername, params.password, attributeList);
728
- if (params.signup_confirmation) {
729
- cognitoUser = newUser.cognitoUser;
730
- this.__request_signup_confirmation = newUser.cognitoUsername;
731
- return "SUCCESS: The account has been created. User's signup confirmation is required.";
732
- }
733
- else if (logUser) {
734
- return login.bind(this)({ email: params.username || params.email, password: params.password });
735
- }
736
- return 'SUCCESS: The account has been created.';
737
- }
738
- export async function disableAccount() {
739
- await this.__connection;
740
- let result = await request.bind(this)('remove-account', { disable: this.__user.user_id }, { auth: true });
741
- await logout.bind(this)();
742
- return result;
743
- }
744
- export async function resetPassword(form) {
745
- await this.__connection;
746
- let params = validator.Params(form, {
747
- email: (v) => validator.Email(v),
748
- code: ['number', 'string'],
749
- new_password: (v) => validator.Password(v)
750
- }, ['email', 'code', 'new_password']);
751
- let code = params.code, new_password = params.new_password;
752
- if (typeof code === 'number') {
753
- code = code.toString();
754
- }
755
- return new Promise(async (res, rej) => {
756
- let cognitoUser = authentication.bind(this)().createCognitoUser(params.email).cognitoUser;
757
- cognitoUser.confirmPassword(code, new_password, {
758
- onSuccess: result => {
759
- res("SUCCESS: New password has been set.");
760
- },
761
- onFailure: (err) => {
762
- rej(new SkapiError(err?.message || 'Failed to reset password.', { code: err?.code || 'ERROR', cause: err }));
763
- }
764
- });
765
- });
766
- }
767
- async function verifyAttribute(attribute, form) {
768
- await this.__connection;
769
- let code;
770
- if (!cognitoUser) {
771
- throw new SkapiError('The user has to be logged in.', { code: 'INVALID_REQUEST' });
772
- }
773
- if (attribute === 'email' || attribute === 'phone_number') {
774
- if (!this.__user.hasOwnProperty(attribute)) {
775
- throw new SkapiError(`No ${attribute === 'email' ? 'e-mail' : 'phone number'} to verify`, { code: 'INVALID_REQUEST' });
776
- }
777
- if (this.__user?.[`${attribute}_verified`]) {
778
- return `SUCCESS: "${attribute}" is verified.`;
779
- }
780
- code = (form ? validator.Params(form, {
781
- code: ['string']
782
- }) : {}).code || '';
783
- }
784
- else {
785
- return;
786
- }
787
- return new Promise((res, rej) => {
788
- let callback = {
789
- onSuccess: (result) => {
790
- if (code) {
791
- authentication.bind(this)().getSession({ refreshToken: true }).then(() => {
792
- if (this.__user) {
793
- this.__user[attribute + '_verified'] = true;
794
- }
795
- res(`SUCCESS: "${attribute}" is verified.`);
796
- }).catch(err => {
797
- rej(err);
798
- });
799
- }
800
- else {
801
- res('SUCCESS: Verification code has been sent.');
802
- }
803
- },
804
- onFailure: (err) => {
805
- rej(new SkapiError(err.message || 'Failed to request verification code.', {
806
- code: err?.code
807
- }));
808
- }
809
- };
810
- if (code) {
811
- cognitoUser?.verifyAttribute(attribute, code, callback);
812
- }
813
- else {
814
- callback.inputVerificationCode = null;
815
- cognitoUser?.getAttributeVerificationCode(attribute, callback);
816
- }
817
- });
818
- }
819
- export function verifyPhoneNumber(form) {
820
- return verifyAttribute.bind(this)('phone_number', form);
821
- }
822
- export function verifyEmail(form) {
823
- return verifyAttribute.bind(this)('email', form);
824
- }
825
- export async function forgotPassword(form) {
826
- await this.__connection;
827
- let params = validator.Params(form, {
828
- email: (v) => validator.Email(v)
829
- }, ['email']);
830
- return new Promise(async (res, rej) => {
831
- let cognitoUser = authentication.bind(this)().createCognitoUser(params.email).cognitoUser;
832
- cognitoUser.forgotPassword({
833
- onSuccess: result => {
834
- res("SUCCESS: Verification code has been sent.");
835
- },
836
- onFailure: (err) => {
837
- let code = 'ERROR';
838
- switch (err?.code) {
839
- case 'UserNotFoundException':
840
- code = 'NOT_EXISTS';
841
- break;
842
- case 'InvalidParameterException':
843
- code = 'INVALID_PARAMETER';
844
- break;
845
- case 'NotAuthorizedException':
846
- code = 'INVALID_REQUEST';
847
- break;
848
- case 'LimitExceededException':
849
- code = 'REQUEST_EXCEED';
850
- break;
851
- case 'TooManyRequestsException':
852
- code = 'REQUEST_EXCEED';
853
- break;
854
- case 'CodeDeliveryFailureException':
855
- code = 'CODE_DELIVERY_FAILURE';
856
- break;
857
- }
858
- rej(new SkapiError(err?.message || 'Failed to send verification code.', { code, cause: err }));
859
- }
860
- });
861
- });
862
- }
863
- export async function changePassword(params) {
864
- await this.__connection;
865
- if (!this.session) {
866
- throw new SkapiError('User login is required.', { code: 'INVALID_REQUEST' });
867
- }
868
- let p = validator.Params(params, {
869
- 'current_password': 'string',
870
- 'new_password': 'string'
871
- });
872
- if (!p?.current_password) {
873
- throw new SkapiError('"current_password" is required to change password.', { code: 'INVALID_PARAMETER' });
874
- }
875
- if (!p?.new_password) {
876
- throw new SkapiError('"new_password" is required to change password.', { code: 'INVALID_PARAMETER' });
877
- }
878
- validator.Password(p.current_password);
879
- validator.Password(p.new_password);
880
- return new Promise((res, rej) => {
881
- cognitoUser.changePassword(p.current_password, p.new_password, (err, result) => {
882
- if (err) {
883
- if (err?.code === "InvalidParameterException") {
884
- rej(new SkapiError('Invalid password parameter.', { code: 'INVALID_PARAMETER' }));
885
- }
886
- else if (err?.code === "NotAuthorizedException") {
887
- rej(new SkapiError('Incorrect password.', { code: 'INVALID_REQUEST' }));
888
- }
889
- else if (err?.code === "TooManyRequestsException" || err?.code === "LimitExceededException") {
890
- rej(new SkapiError('Too many attempts. Please try again later.', { code: 'REQUEST_EXCEED' }));
891
- }
892
- else {
893
- rej(new SkapiError(err?.message || 'Failed to change user password.', { code: err?.code || 'ERROR', cause: err }));
894
- }
895
- }
896
- res('SUCCESS: Password has been changed.');
897
- });
898
- });
899
- }
900
- export async function updateProfile(form) {
901
- await this.__connection;
902
- if (!this.session) {
903
- throw new SkapiError('User login is required.', { code: 'INVALID_REQUEST' });
904
- }
905
- let params = validator.Params(form || {}, {
906
- user_id: (v) => validator.UserId(v),
907
- email: (v) => validator.Email(v),
908
- address: (v) => {
909
- if (!v)
910
- return '';
911
- if (typeof v === 'string') {
912
- return v;
913
- }
914
- if (typeof v === 'object') {
915
- return JSON.stringify(v);
916
- }
917
- return undefined;
918
- },
919
- name: 'string',
920
- gender: 'string',
921
- birthdate: (v) => v ? validator.Birthdate(v) : "",
922
- phone_number: (v) => v ? validator.PhoneNumber(v) : "",
923
- email_public: 'boolean',
924
- phone_number_public: 'boolean',
925
- address_public: 'boolean',
926
- gender_public: 'boolean',
927
- birthdate_public: 'boolean',
928
- misc: 'string',
929
- picture: (v) => v ? validator.Url(v) : "",
930
- profile: (v) => v ? validator.Url(v) : "",
931
- family_name: 'string',
932
- given_name: 'string',
933
- middle_name: 'string',
934
- nickname: 'string',
935
- website: (v) => v ? validator.Url(v) : "",
936
- });
937
- if (params && typeof params === 'object' && !Object.keys(params).length) {
938
- return this.user;
939
- }
940
- if (params.email) {
941
- params['preferred_username'] = this.service + '-' + MD5.hash(params.email);
942
- }
943
- let collision = [
944
- ['email_public', 'email_verified', "User's e-mail should be verified to set"],
945
- ['phone_number_public', 'phone_number_verified', "User's phone number should be verified to set"]
946
- ];
947
- if (this.__user) {
948
- for (let c of collision) {
949
- if (params[c[0]] && !this.__user[c[1]]) {
950
- throw new SkapiError(`${c[2]} "${c[0]}" to true.`, { code: 'INVALID_REQUEST' });
951
- }
952
- }
953
- }
954
- let toRemove = [];
955
- for (let k in params) {
956
- if (params[k] === this.user[k]) {
957
- toRemove.push(k);
958
- continue;
959
- }
960
- let customAttr = [
961
- 'email_public',
962
- 'phone_number_public',
963
- 'address_public',
964
- 'gender_public',
965
- 'birthdate_public',
966
- 'misc'
967
- ];
968
- if (customAttr.includes(k)) {
969
- let parseValue = params[k];
970
- if (typeof parseValue === 'boolean') {
971
- parseValue = parseValue ? '1' : '0';
972
- }
973
- params['custom:' + k] = parseValue;
974
- toRemove.push(k);
975
- }
976
- }
977
- for (let k of toRemove) {
978
- delete params[k];
979
- }
980
- if (params.user_id) {
981
- let user_id = params.user_id;
982
- if (user_id === this.user.user_id) {
983
- delete params.user_id;
984
- }
985
- else {
986
- return request.bind(this)('admin-edit-profile', { attributes: params }, { auth: true });
987
- }
988
- }
989
- if (params && typeof params === 'object' && Object.keys(params).length) {
990
- let toSet = [];
991
- for (let key in params) {
992
- toSet.push(new CognitoUserAttribute({
993
- Name: key,
994
- Value: params[key]
995
- }));
996
- }
997
- await new Promise((res, rej) => {
998
- cognitoUser?.updateAttributes(toSet, (err, result) => {
999
- if (err) {
1000
- rej([
1001
- err?.code || err?.name,
1002
- err?.message || `Failed to update user settings.`
1003
- ]);
1004
- }
1005
- res(result);
1006
- });
1007
- });
1008
- await authentication.bind(this)().getSession({ refreshToken: true });
1009
- return this.user;
1010
- }
1011
- return this.user;
1012
- }
1013
- export async function getUsers(params, fetchOptions) {
1014
- params = extractFormData(params).data;
1015
- if (!params) {
1016
- params = {
1017
- searchFor: 'timestamp',
1018
- condition: '>',
1019
- value: 0
1020
- };
1021
- if (!fetchOptions) {
1022
- fetchOptions = {};
1023
- }
1024
- fetchOptions.ascending = false;
1025
- }
1026
- await this.__connection;
1027
- const searchForTypes = {
1028
- 'user_id': (v) => {
1029
- if (Array.isArray(v)) {
1030
- return v.map(id => validator.UserId(id));
1031
- }
1032
- return validator.UserId(v);
1033
- },
1034
- 'email': 'string',
1035
- 'phone_number': 'string',
1036
- 'locale': (v) => {
1037
- if (typeof v !== 'string' || typeof v === 'string' && v.length > 5) {
1038
- throw new SkapiError('Value of "locale" should be a country code.', { code: 'INVALID_PARAMETER' });
1039
- }
1040
- return v;
1041
- },
1042
- 'name': 'string',
1043
- 'address': 'string',
1044
- 'gender': 'string',
1045
- 'birthdate': (v) => validator.Birthdate(v),
1046
- 'subscribers': 'number',
1047
- 'timestamp': 'number',
1048
- 'access_group': 'number',
1049
- 'approved': 'string'
1050
- };
1051
- let required = ['searchFor', 'value'];
1052
- params = validator.Params(params, {
1053
- searchFor: [
1054
- 'user_id',
1055
- 'name',
1056
- 'email',
1057
- 'phone_number',
1058
- 'address',
1059
- 'gender',
1060
- 'birthdate',
1061
- 'locale',
1062
- 'subscribers',
1063
- 'timestamp',
1064
- 'access_group',
1065
- 'approved'
1066
- ],
1067
- condition: ['>', '>=', '=', '<', '<=', 'gt', 'gte', 'eq', 'lt', 'lte', () => '='],
1068
- value: (v) => {
1069
- let checker = searchForTypes[params.searchFor];
1070
- if (typeof checker === 'function') {
1071
- return checker(v);
1072
- }
1073
- else if (typeof v !== checker) {
1074
- throw new SkapiError(`Value does not match the type of "${params.searchFor}" index.`, { code: 'INVALID_PARAMETER' });
1075
- }
1076
- return v;
1077
- },
1078
- range: (v) => {
1079
- let checker = searchForTypes[params.searchFor];
1080
- if (typeof checker === 'function') {
1081
- return checker(v);
1082
- }
1083
- else if (typeof v !== checker) {
1084
- throw new SkapiError(`Range does not match the type of "${params.searchFor}" index.`, { code: 'INVALID_PARAMETER' });
1085
- }
1086
- return v;
1087
- }
1088
- }, required);
1089
- if (params?.condition && params?.condition !== '=' && params.hasOwnProperty('range')) {
1090
- throw new SkapiError('Conditions does not apply on range search.', { code: 'INVALID_PARAMETER' });
1091
- }
1092
- if (params.searchFor === 'user_id' && (params.condition !== '=' || params.range)) {
1093
- throw new SkapiError(`Conditions are not allowed on "${params.searchFor}"`, { code: 'INVALID_PARAMETER' });
1094
- }
1095
- if (typeof params?.value === 'string' && !params?.value) {
1096
- throw new SkapiError('Value should not be an empty string.', { code: 'INVALID_PARAMETER' });
1097
- }
1098
- if (typeof params?.searchFor === 'string' && !params?.searchFor) {
1099
- throw new SkapiError('"searchFor" should not be an empty string.', { code: 'INVALID_PARAMETER' });
1100
- }
1101
- return request.bind(this)('get-users', params, { auth: true, fetchOptions });
1102
- }
1103
- export async function lastVerifiedEmail(params) {
1104
- await this.__connection;
1105
- let res = await request.bind(this)('last-verified-email', params, { auth: true });
1106
- if (res.includes('SUCCESS')) {
1107
- await authentication.bind(this)().getSession({ refreshToken: true });
1108
- return this.user;
1109
- }
1110
- return res;
1111
- }
1112
- export async function requestUsernameChange(params) {
1113
- await this.__connection;
1114
- params = validator.Params(params, {
1115
- username: validator.Email,
1116
- redirect: validator.Url
1117
- }, ['username']);
1118
- return await request.bind(this)('request-username-change', params, { auth: true });
1119
- }
1120
- //# sourceMappingURL=user.js.map