@progalaxyelabs/ngx-stonescriptphp-client 1.15.0 → 1.16.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.
@@ -417,22 +417,48 @@ class StoneScriptPHPAuth {
417
417
  resolve({ success: false, message: 'Popup blocked. Please allow popups for this site.' });
418
418
  return;
419
419
  }
420
+ const cleanup = () => {
421
+ window.removeEventListener('message', messageHandler);
422
+ clearInterval(checkClosed);
423
+ if (popup && !popup.closed)
424
+ popup.close();
425
+ };
420
426
  const messageHandler = (event) => {
421
427
  if (event.origin !== new URL(accountsUrl).origin)
422
428
  return;
423
- if (event.data.type === 'oauth_success') {
424
- window.removeEventListener('message', messageHandler);
425
- popup.close();
429
+ if (event.data.type === 'oauth_new_identity') {
430
+ cleanup();
431
+ resolve({
432
+ success: true,
433
+ accessToken: event.data.access_token,
434
+ refreshToken: event.data.refresh_token,
435
+ isNewIdentity: true,
436
+ authMethod: event.data.auth_method,
437
+ oauthProvider: event.data.oauth_provider,
438
+ identity: event.data.identity,
439
+ });
440
+ }
441
+ else if (event.data.type === 'oauth_success') {
442
+ cleanup();
426
443
  const rawUser = event.data.user || this.resolveUser(event.data);
427
444
  resolve({
428
445
  success: true,
429
446
  accessToken: event.data.access_token,
430
- user: rawUser ? this.normalizeUser(rawUser) : undefined
447
+ refreshToken: event.data.refresh_token,
448
+ user: rawUser ? this.normalizeUser(rawUser) : undefined,
449
+ membership: event.data.membership,
450
+ });
451
+ }
452
+ else if (event.data.type === 'oauth_tenant_selection') {
453
+ cleanup();
454
+ resolve({
455
+ success: true,
456
+ accessToken: event.data.selection_token,
457
+ memberships: event.data.memberships,
431
458
  });
432
459
  }
433
460
  else if (event.data.type === 'oauth_error') {
434
- window.removeEventListener('message', messageHandler);
435
- popup.close();
461
+ cleanup();
436
462
  resolve({ success: false, message: event.data.message || 'OAuth login failed' });
437
463
  }
438
464
  };
@@ -609,6 +635,26 @@ class StoneScriptPHPAuth {
609
635
  }
610
636
  return response.json();
611
637
  }
638
+ async provisionTenant(storeName, countryCode, accessToken) {
639
+ const apiUrl = this.getPlatformApiUrl();
640
+ const response = await fetch(`${apiUrl}/auth/provision-tenant`, {
641
+ method: 'POST',
642
+ headers: {
643
+ 'Content-Type': 'application/json',
644
+ 'Authorization': `Bearer ${accessToken}`
645
+ },
646
+ credentials: 'include',
647
+ body: JSON.stringify({
648
+ store_name: storeName,
649
+ country_code: countryCode,
650
+ })
651
+ });
652
+ if (!response.ok) {
653
+ const errorData = await response.json();
654
+ throw new Error(errorData.message || 'Failed to provision tenant');
655
+ }
656
+ return response.json();
657
+ }
612
658
  async checkEmail(email) {
613
659
  try {
614
660
  const accountsUrl = this.getAccountsUrl();
@@ -1033,6 +1079,17 @@ class AuthService {
1033
1079
  throw new Error('checkOnboardingStatus not supported');
1034
1080
  return this.plugin.checkOnboardingStatus(identityId);
1035
1081
  }
1082
+ async provisionTenant(storeName, countryCode = 'IN') {
1083
+ if (!this.plugin.provisionTenant) {
1084
+ throw new Error('provisionTenant not supported by the configured auth plugin');
1085
+ }
1086
+ const result = await this.plugin.provisionTenant(storeName, countryCode, this.tokens.getAccessToken());
1087
+ if (result?.access_token) {
1088
+ this.tokens.setAccessToken(result.access_token);
1089
+ this.signinStatus.setSigninStatus(true);
1090
+ }
1091
+ return result;
1092
+ }
1036
1093
  async completeTenantOnboarding(countryCode, tenantName, serverName) {
1037
1094
  if (!this.plugin.completeTenantOnboarding)
1038
1095
  throw new Error('completeTenantOnboarding not supported');
@@ -1781,6 +1838,7 @@ class TenantLoginComponent {
1781
1838
  createTenantLinkAction = 'Create New Organization';
1782
1839
  // Outputs
1783
1840
  tenantSelected = new EventEmitter();
1841
+ needsOnboarding = new EventEmitter();
1784
1842
  createTenant = new EventEmitter();
1785
1843
  // Form Fields
1786
1844
  email = '';
@@ -1868,7 +1926,23 @@ class TenantLoginComponent {
1868
1926
  this.error = result.message || 'OAuth login failed';
1869
1927
  return;
1870
1928
  }
1871
- // Authentication successfulpass result so membership can be reused if present
1929
+ // New identityuser exists but has no tenant membership
1930
+ if (result.isNewIdentity && result.identity) {
1931
+ this.needsOnboarding.emit({
1932
+ auth_method: result.authMethod || 'oauth',
1933
+ oauth_provider: result.oauthProvider,
1934
+ is_new_identity: true,
1935
+ identity: result.identity,
1936
+ });
1937
+ return;
1938
+ }
1939
+ // Multi-tenant selection — user has multiple memberships
1940
+ if (result.memberships && result.memberships.length > 0) {
1941
+ this.memberships = result.memberships;
1942
+ this.showingTenantSelector = true;
1943
+ return;
1944
+ }
1945
+ // Standard success — pass result so membership can be reused if present
1872
1946
  await this.handlePostAuthFlow(result);
1873
1947
  }
1874
1948
  catch (err) {
@@ -1997,7 +2071,7 @@ class TenantLoginComponent {
1997
2071
  this.createTenant.emit();
1998
2072
  }
1999
2073
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TenantLoginComponent, deps: [{ token: AuthService }, { token: ProviderRegistryService }], target: i0.ɵɵFactoryTarget.Component });
2000
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: TenantLoginComponent, isStandalone: true, selector: "lib-tenant-login", inputs: { title: "title", providers: "providers", showTenantSelector: "showTenantSelector", autoSelectSingleTenant: "autoSelectSingleTenant", prefillEmail: "prefillEmail", allowTenantCreation: "allowTenantCreation", tenantSelectorTitle: "tenantSelectorTitle", tenantSelectorDescription: "tenantSelectorDescription", continueButtonText: "continueButtonText", registerLinkText: "registerLinkText", registerLinkAction: "registerLinkAction", createTenantLinkText: "createTenantLinkText", createTenantLinkAction: "createTenantLinkAction" }, outputs: { tenantSelected: "tenantSelected", createTenant: "createTenant" }, ngImport: i0, template: `
2074
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: TenantLoginComponent, isStandalone: true, selector: "lib-tenant-login", inputs: { title: "title", providers: "providers", showTenantSelector: "showTenantSelector", autoSelectSingleTenant: "autoSelectSingleTenant", prefillEmail: "prefillEmail", allowTenantCreation: "allowTenantCreation", tenantSelectorTitle: "tenantSelectorTitle", tenantSelectorDescription: "tenantSelectorDescription", continueButtonText: "continueButtonText", registerLinkText: "registerLinkText", registerLinkAction: "registerLinkAction", createTenantLinkText: "createTenantLinkText", createTenantLinkAction: "createTenantLinkAction" }, outputs: { tenantSelected: "tenantSelected", needsOnboarding: "needsOnboarding", createTenant: "createTenant" }, ngImport: i0, template: `
2001
2075
  <div class="tenant-login-dialog">
2002
2076
  @if (!showingTenantSelector) {
2003
2077
  <!-- Step 1: Authentication -->
@@ -2362,6 +2436,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
2362
2436
  type: Input
2363
2437
  }], tenantSelected: [{
2364
2438
  type: Output
2439
+ }], needsOnboarding: [{
2440
+ type: Output
2365
2441
  }], createTenant: [{
2366
2442
  type: Output
2367
2443
  }] } });
@@ -2812,7 +2888,7 @@ class AuthPageComponent {
2812
2888
  }
2813
2889
  </div>
2814
2890
  </div>
2815
- `, isInline: true, styles: [".auth-container{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;background:linear-gradient(135deg,#667eea,#764ba2)}.auth-card{background:#fff;border-radius:12px;box-shadow:0 10px 40px #0000001a;padding:40px;width:100%;max-width:480px}.logo{display:block;max-width:200px;max-height:80px;margin:0 auto 24px}.app-name{margin:0 0 12px;font-size:28px;font-weight:600;text-align:center;color:#1a202c}.subtitle{margin:0 0 32px;font-size:16px;text-align:center;color:#718096}:host ::ng-deep .tenant-login-dialog,:host ::ng-deep .register-dialog{padding:0;max-width:none}:host ::ng-deep .login-title,:host ::ng-deep .register-title{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TenantLoginComponent, selector: "lib-tenant-login", inputs: ["title", "providers", "showTenantSelector", "autoSelectSingleTenant", "prefillEmail", "allowTenantCreation", "tenantSelectorTitle", "tenantSelectorDescription", "continueButtonText", "registerLinkText", "registerLinkAction", "createTenantLinkText", "createTenantLinkAction"], outputs: ["tenantSelected", "createTenant"] }, { kind: "component", type: RegisterComponent, selector: "lib-register", outputs: ["navigateToLogin"] }] });
2891
+ `, isInline: true, styles: [".auth-container{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;background:linear-gradient(135deg,#667eea,#764ba2)}.auth-card{background:#fff;border-radius:12px;box-shadow:0 10px 40px #0000001a;padding:40px;width:100%;max-width:480px}.logo{display:block;max-width:200px;max-height:80px;margin:0 auto 24px}.app-name{margin:0 0 12px;font-size:28px;font-weight:600;text-align:center;color:#1a202c}.subtitle{margin:0 0 32px;font-size:16px;text-align:center;color:#718096}:host ::ng-deep .tenant-login-dialog,:host ::ng-deep .register-dialog{padding:0;max-width:none}:host ::ng-deep .login-title,:host ::ng-deep .register-title{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TenantLoginComponent, selector: "lib-tenant-login", inputs: ["title", "providers", "showTenantSelector", "autoSelectSingleTenant", "prefillEmail", "allowTenantCreation", "tenantSelectorTitle", "tenantSelectorDescription", "continueButtonText", "registerLinkText", "registerLinkAction", "createTenantLinkText", "createTenantLinkAction"], outputs: ["tenantSelected", "needsOnboarding", "createTenant"] }, { kind: "component", type: RegisterComponent, selector: "lib-register", outputs: ["navigateToLogin"] }] });
2816
2892
  }
2817
2893
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AuthPageComponent, decorators: [{
2818
2894
  type: Component,
@@ -3867,7 +3943,7 @@ class TenantLoginDialogComponent {
3867
3943
  (createTenant)="onCreateTenant()">
3868
3944
  </lib-tenant-login>
3869
3945
  </div>
3870
- `, isInline: true, styles: [".dialog-wrapper{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TenantLoginComponent, selector: "lib-tenant-login", inputs: ["title", "providers", "showTenantSelector", "autoSelectSingleTenant", "prefillEmail", "allowTenantCreation", "tenantSelectorTitle", "tenantSelectorDescription", "continueButtonText", "registerLinkText", "registerLinkAction", "createTenantLinkText", "createTenantLinkAction"], outputs: ["tenantSelected", "createTenant"] }] });
3946
+ `, isInline: true, styles: [".dialog-wrapper{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TenantLoginComponent, selector: "lib-tenant-login", inputs: ["title", "providers", "showTenantSelector", "autoSelectSingleTenant", "prefillEmail", "allowTenantCreation", "tenantSelectorTitle", "tenantSelectorDescription", "continueButtonText", "registerLinkText", "registerLinkAction", "createTenantLinkText", "createTenantLinkAction"], outputs: ["tenantSelected", "needsOnboarding", "createTenant"] }] });
3871
3947
  }
3872
3948
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TenantLoginDialogComponent, decorators: [{
3873
3949
  type: Component,