@idp.global/sdk 14.3.0 → 14.4.1

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.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@idp.global/sdk',
6
- version: '14.3.0',
6
+ version: '14.4.1',
7
7
  description: 'Reusable browser and server SDK for idp.global authentication.'
8
8
  }
@@ -1,6 +1,13 @@
1
1
  import { IdpRequests } from './classes.idprequests.js';
2
2
  import * as plugins from './plugins.js';
3
3
 
4
+ export type TIdpClientTransport = 'websocket' | 'http';
5
+
6
+ export interface IIdpClientOptions {
7
+ transport?: TIdpClientTransport;
8
+ loginBaseUrl?: string;
9
+ }
10
+
4
11
  export class IdpClient {
5
12
  private helpers = {
6
13
  async extractDataFromJwtString(jwtString: string): Promise<plugins.idpInterfaces.data.IJwt> {
@@ -13,10 +20,13 @@ export class IdpClient {
13
20
  public organizationsReplaySubject = new plugins.smartrx.rxjs.ReplaySubject(1);
14
21
 
15
22
  public parsedReceptionUrl: plugins.smarturl.Smarturl;
23
+ public parsedLoginUrl: plugins.smarturl.Smarturl;
24
+ public readonly transport: TIdpClientTransport;
16
25
 
17
26
  constructor(
18
27
  receptionBaseUrlArg: string,
19
- transferTargetArg?: plugins.idpInterfaces.data.ITransferTarget
28
+ transferTargetArg?: plugins.idpInterfaces.data.ITransferTarget,
29
+ optionsArg: IIdpClientOptions = {},
20
30
  ) {
21
31
  if (receptionBaseUrlArg.endsWith('/')) {
22
32
  receptionBaseUrlArg = receptionBaseUrlArg.slice(0, -1);
@@ -25,6 +35,9 @@ export class IdpClient {
25
35
  receptionBaseUrlArg = `${receptionBaseUrlArg}/typedrequest`;
26
36
  }
27
37
  this.parsedReceptionUrl = plugins.smarturl.Smarturl.createFromUrl(receptionBaseUrlArg);
38
+ const loginBaseUrl = optionsArg.loginBaseUrl || this.parsedReceptionUrl.origin;
39
+ this.parsedLoginUrl = plugins.smarturl.Smarturl.createFromUrl(loginBaseUrl);
40
+ this.transport = optionsArg.transport || 'websocket';
28
41
  this.#transferTargetAppUrl = this.normalizeTransferTargetAppUrl(
29
42
  transferTargetArg || {
30
43
  appUrl: typeof window !== 'undefined' ? window.location.origin : '',
@@ -38,6 +51,27 @@ export class IdpClient {
38
51
 
39
52
  public requests = new IdpRequests(this);
40
53
 
54
+ public createTypedRequest<
55
+ TRequest extends plugins.typedrequestInterfaces.ITypedRequest,
56
+ >(methodArg: TRequest['method']) {
57
+ if (this.transport === 'http') {
58
+ return new plugins.typedrequest.TypedRequest<TRequest>(
59
+ this.parsedReceptionUrl.href,
60
+ methodArg,
61
+ );
62
+ }
63
+ if (!this.typedsocket) {
64
+ throw new Error('TypedSocket has not been enabled for this IdpClient.');
65
+ }
66
+ return this.typedsocket.createTypedRequest<TRequest>(methodArg);
67
+ }
68
+
69
+ private async ensureTransportReady(): Promise<void> {
70
+ if (this.transport === 'websocket') {
71
+ await this.enableTypedSocket();
72
+ }
73
+ }
74
+
41
75
  public checkWetherOnReceptionDomain() {
42
76
  return plugins.smarturl.Smarturl.createFromUrl(window.location.href).hostname ===
43
77
  this.parsedReceptionUrl.hostname;
@@ -129,8 +163,8 @@ export class IdpClient {
129
163
  return null;
130
164
  }
131
165
 
132
- await this.enableTypedSocket();
133
- const refreshJwtReq = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_RefreshJwt>('refreshJwt');
166
+ await this.ensureTransportReady();
167
+ const refreshJwtReq = this.createTypedRequest<plugins.idpInterfaces.request.IReq_RefreshJwt>('refreshJwt');
134
168
  const response = await refreshJwtReq.fire({ refreshToken }).catch(async (error) => {
135
169
  if (this.isAuthInvalidResponse(error)) {
136
170
  await this.clearAuthState();
@@ -162,8 +196,8 @@ export class IdpClient {
162
196
  }
163
197
 
164
198
  private async validateJwtWithServer(jwtStringArg: string): Promise<boolean> {
165
- await this.enableTypedSocket();
166
- const whoIs = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_WhoIs>('whoIs');
199
+ await this.ensureTransportReady();
200
+ const whoIs = this.createTypedRequest<plugins.idpInterfaces.request.IReq_WhoIs>('whoIs');
167
201
  try {
168
202
  await whoIs.fire({ jwt: jwtStringArg });
169
203
  return true;
@@ -189,8 +223,8 @@ export class IdpClient {
189
223
  if (!refreshToken) {
190
224
  return null;
191
225
  }
192
- await this.enableTypedSocket();
193
- const getTransferToken = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_ExchangeRefreshTokenAndTransferToken>('exchangeRefreshTokenAndTransferToken');
226
+ await this.ensureTransportReady();
227
+ const getTransferToken = this.createTypedRequest<plugins.idpInterfaces.request.IReq_ExchangeRefreshTokenAndTransferToken>('exchangeRefreshTokenAndTransferToken');
194
228
  const response = await getTransferToken.fire({
195
229
  refreshToken,
196
230
  transferTarget: transferTargetArg,
@@ -228,8 +262,8 @@ export class IdpClient {
228
262
  const transferToken = url.searchParams['transfertoken'];
229
263
  if (transferToken) {
230
264
  this.scrubTransferTokenFromCurrentUrl();
231
- await this.enableTypedSocket();
232
- const getTransferToken = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_ExchangeRefreshTokenAndTransferToken>('exchangeRefreshTokenAndTransferToken');
265
+ await this.ensureTransportReady();
266
+ const getTransferToken = this.createTypedRequest<plugins.idpInterfaces.request.IReq_ExchangeRefreshTokenAndTransferToken>('exchangeRefreshTokenAndTransferToken');
233
267
  const response = await getTransferToken.fire({
234
268
  transferToken,
235
269
  transferTarget: this.transferTarget,
@@ -271,7 +305,7 @@ export class IdpClient {
271
305
  }
272
306
  if (requireLoginArg) {
273
307
  const urlInstance = plugins.smarturl.Smarturl.createFromUrl(
274
- this.parsedReceptionUrl.clone().set('path', '/login').toString(),
308
+ this.parsedLoginUrl.clone().set('path', '/login').toString(),
275
309
  {
276
310
  searchParams: {
277
311
  transfertarget: plugins.smartjson.stringifyBase64(this.transferTarget),
@@ -291,8 +325,8 @@ export class IdpClient {
291
325
  * available.
292
326
  */
293
327
  public async discoverSsoForEmail(emailArg: string): Promise<{ ssoAvailable: boolean; loginUrl?: string }> {
294
- await this.enableTypedSocket();
295
- const discoverTr = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_DiscoverSsoForEmail>('discoverSsoForEmail');
328
+ await this.ensureTransportReady();
329
+ const discoverTr = this.createTypedRequest<plugins.idpInterfaces.request.IReq_DiscoverSsoForEmail>('discoverSsoForEmail');
296
330
  return await discoverTr.fire({ email: emailArg });
297
331
  }
298
332
 
@@ -331,8 +365,8 @@ export class IdpClient {
331
365
  }
332
366
  return;
333
367
  }
334
- await this.enableTypedSocket();
335
- const logoutTr = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.ILogoutRequest>('logout');
368
+ await this.ensureTransportReady();
369
+ const logoutTr = this.createTypedRequest<plugins.idpInterfaces.request.ILogoutRequest>('logout');
336
370
  await logoutTr.fire({ refreshToken });
337
371
  await this.clearAuthState();
338
372
  if (!redirect) {
@@ -348,6 +382,9 @@ export class IdpClient {
348
382
  public typedsocketDeferred = plugins.smartpromise.defer<plugins.typedsocket.TypedSocket>();
349
383
 
350
384
  public async enableTypedSocket() {
385
+ if (this.transport !== 'websocket') {
386
+ throw new Error('This IdpClient is configured for HTTP transport.');
387
+ }
351
388
  if (this.typedsocketDeferred.claimed) {
352
389
  return this.typedsocketDeferred.promise;
353
390
  }
@@ -382,15 +419,19 @@ export class IdpClient {
382
419
  public async stop() {
383
420
  this.typedsocketStopRequested = true;
384
421
  this.typedsocketAbortController?.abort();
385
- await this.typedsocket?.stop();
386
- if (this.typedsocketDeferred.status === 'fulfilled') {
387
- this.typedsocketDeferred = plugins.smartpromise.defer<plugins.typedsocket.TypedSocket>();
422
+ try {
423
+ await this.typedsocket?.stop();
424
+ } finally {
425
+ if (this.typedsocketDeferred.status === 'fulfilled') {
426
+ this.typedsocketDeferred = plugins.smartpromise.defer<plugins.typedsocket.TypedSocket>();
427
+ }
428
+ await this.ssoStore.close();
388
429
  }
389
430
  }
390
431
 
391
432
  public async createOrganization(orgNameArg: string, orgSlugArg: string, modeArg: 'checkAvailability' | 'manifest') {
392
- await this.enableTypedSocket();
393
- const validateOrg = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_CreateOrganization>('createOrganization');
433
+ await this.ensureTransportReady();
434
+ const validateOrg = this.createTypedRequest<plugins.idpInterfaces.request.IReq_CreateOrganization>('createOrganization');
394
435
  return validateOrg.fire({
395
436
  jwt: await this.getJwt(),
396
437
  action: modeArg,
@@ -401,8 +442,8 @@ export class IdpClient {
401
442
  }
402
443
 
403
444
  public async getRolesAndOrganizations() {
404
- await this.enableTypedSocket();
405
- const rolesAndOrganizationsForUserId = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_GetRolesAndOrganizationsForUserId>('getRolesAndOrganizationsForUserId');
445
+ await this.ensureTransportReady();
446
+ const rolesAndOrganizationsForUserId = this.createTypedRequest<plugins.idpInterfaces.request.IReq_GetRolesAndOrganizationsForUserId>('getRolesAndOrganizationsForUserId');
406
447
  return rolesAndOrganizationsForUserId.fire({
407
448
  jwt: await this.getJwt(),
408
449
  userId: (await this.getJwtData()).id,
@@ -410,8 +451,8 @@ export class IdpClient {
410
451
  }
411
452
 
412
453
  public async updatePaddleCheckoutId(orgIdArg: string, checkoutIdArg: string) {
413
- await this.enableTypedSocket();
414
- const updateBillingPlan = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_UpdatePaymentMethod>('updatePaymentMethod');
454
+ await this.ensureTransportReady();
455
+ const updateBillingPlan = this.createTypedRequest<plugins.idpInterfaces.request.IReq_UpdatePaymentMethod>('updatePaymentMethod');
415
456
  return updateBillingPlan.fire({
416
457
  jwtString: await this.getJwt(),
417
458
  orgId: orgIdArg,
@@ -420,8 +461,8 @@ export class IdpClient {
420
461
  }
421
462
 
422
463
  public async whoIs() {
423
- await this.enableTypedSocket();
424
- const whoIs = this.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_WhoIs>('whoIs');
464
+ await this.ensureTransportReady();
465
+ const whoIs = this.createTypedRequest<plugins.idpInterfaces.request.IReq_WhoIs>('whoIs');
425
466
  return whoIs.fire({ jwt: await this.getJwt() });
426
467
  }
427
468
  }