@progalaxyelabs/ngx-stonescriptphp-client 1.12.0 → 1.15.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.
@@ -140,19 +140,36 @@ class StoneScriptPHPAuth {
140
140
  const raw = this.resolvePath(data, this.responseMap.userPath);
141
141
  return raw ? this.normalizeUser(raw) : undefined;
142
142
  }
143
+ resolveMembership(data) {
144
+ const raw = this.resolvePath(data, 'data.membership');
145
+ return raw ? raw : undefined;
146
+ }
143
147
  resolveErrorMessage(data, fallback) {
144
148
  const path = this.responseMap.errorMessagePath ?? 'message';
145
149
  return this.resolvePath(data, path) || fallback;
146
150
  }
147
151
  normalizeUser(raw) {
148
- return {
149
- user_id: raw.user_id ?? (raw.id ? this.hashUUID(raw.id) : 0),
150
- id: raw.id ?? String(raw.user_id),
152
+ const user = {
151
153
  email: raw.email,
152
154
  display_name: raw.display_name ?? raw.email?.split('@')[0] ?? '',
153
155
  photo_url: raw.photo_url,
154
156
  is_email_verified: raw.is_email_verified ?? false
155
157
  };
158
+ // id and user_id are optional after auth response cleanup (task #1552)
159
+ // Only populate them if the raw data contains them
160
+ if (raw.id) {
161
+ user.id = raw.id;
162
+ }
163
+ else if (raw.user_id) {
164
+ user.id = String(raw.user_id);
165
+ }
166
+ if (raw.user_id) {
167
+ user.user_id = raw.user_id;
168
+ }
169
+ else if (raw.id) {
170
+ user.user_id = this.hashUUID(raw.id);
171
+ }
172
+ return user;
156
173
  }
157
174
  hashUUID(uuid) {
158
175
  let hash = 0;
@@ -249,7 +266,8 @@ class StoneScriptPHPAuth {
249
266
  success: true,
250
267
  accessToken: this.resolveAccessToken(data),
251
268
  refreshToken: this.resolveRefreshToken(data),
252
- user: this.resolveUser(data)
269
+ user: this.resolveUser(data),
270
+ membership: this.resolveMembership(data)
253
271
  };
254
272
  }
255
273
  return { success: false, message: this.resolveErrorMessage(data, 'Invalid credentials') };
@@ -454,7 +472,8 @@ class StoneScriptPHPAuth {
454
472
  async getTenantMemberships(accessToken) {
455
473
  try {
456
474
  const accountsUrl = this.getAccountsUrl();
457
- const response = await fetch(`${accountsUrl}/api/auth/memberships`, {
475
+ const platformCode = encodeURIComponent(this.config.platformCode ?? '');
476
+ const response = await fetch(`${accountsUrl}/api/auth/memberships?platform_code=${platformCode}`, {
458
477
  method: 'GET',
459
478
  headers: {
460
479
  'Authorization': `Bearer ${accessToken}`,
@@ -469,7 +488,7 @@ class StoneScriptPHPAuth {
469
488
  return [];
470
489
  }
471
490
  }
472
- async registerTenant(data, accessToken) {
491
+ async registerTenant(data) {
473
492
  if (data.provider !== 'emailPassword') {
474
493
  return this.registerTenantWithOAuth(data.tenantName, data.provider);
475
494
  }
@@ -489,14 +508,15 @@ class StoneScriptPHPAuth {
489
508
  body['role'] = data.role;
490
509
  const response = await fetch(`${apiUrl}/auth/register-tenant`, {
491
510
  method: 'POST',
492
- headers: {
493
- 'Content-Type': 'application/json',
494
- ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {})
495
- },
511
+ headers: { 'Content-Type': 'application/json' },
496
512
  credentials: 'include',
497
513
  body: JSON.stringify(body)
498
514
  });
499
- return response.json();
515
+ const result = await response.json();
516
+ if (result?.status === 'ok' || result?.success === true) {
517
+ return { success: true };
518
+ }
519
+ return { success: false, message: result?.data?.message || result?.message || 'Registration failed' };
500
520
  }
501
521
  catch {
502
522
  return { success: false, message: 'Network error. Please try again.' };
@@ -522,8 +542,11 @@ class StoneScriptPHPAuth {
522
542
  if (event.data.type === 'tenant_register_success') {
523
543
  window.removeEventListener('message', messageHandler);
524
544
  popup.close();
525
- resolve({ success: true, tenant: event.data.tenant, user: event.data.user,
526
- access_token: event.data.access_token });
545
+ resolve({
546
+ success: true,
547
+ accessToken: event.data.access_token,
548
+ user: event.data.user ? this.normalizeUser(event.data.user) : undefined
549
+ });
527
550
  }
528
551
  else if (event.data.type === 'tenant_register_error') {
529
552
  window.removeEventListener('message', messageHandler);
@@ -969,16 +992,20 @@ class AuthService {
969
992
  if (!this.plugin.registerTenant) {
970
993
  return { success: false, message: 'registerTenant not supported by the configured auth plugin' };
971
994
  }
972
- const accessToken = this.tokens.getAccessToken() || undefined;
973
- const result = await this.plugin.registerTenant(data, accessToken);
974
- if (result?.access_token) {
975
- this.tokens.setAccessToken(result.access_token);
976
- this.signinStatus.setSigninStatus(true);
995
+ const registered = await this.plugin.registerTenant(data);
996
+ if (!registered.success)
997
+ return registered;
998
+ // OAuth: token comes directly from the popup — store it and we're done.
999
+ if (registered.accessToken) {
1000
+ this.storeAuthResult(registered);
1001
+ return registered;
977
1002
  }
978
- if (result?.refresh_token) {
979
- this.tokens.setRefreshToken(result.refresh_token);
1003
+ // emailPassword: registration succeeded but no token yet.
1004
+ // Login via auth (SSO) to obtain tokens.
1005
+ if (data.provider === 'emailPassword' && data.email && data.password) {
1006
+ return await this.loginWithEmail(data.email, data.password);
980
1007
  }
981
- return result;
1008
+ return registered;
982
1009
  }
983
1010
  async getTenantMemberships(serverName) {
984
1011
  if (!this.plugin.getTenantMemberships)
@@ -1822,8 +1849,8 @@ class TenantLoginComponent {
1822
1849
  this.error = result.message || 'Login failed';
1823
1850
  return;
1824
1851
  }
1825
- // Authentication successful, now handle tenant selection
1826
- await this.handlePostAuthFlow();
1852
+ // Authentication successful pass result so membership can be reused
1853
+ await this.handlePostAuthFlow(result);
1827
1854
  }
1828
1855
  catch (err) {
1829
1856
  this.error = err.message || 'An unexpected error occurred';
@@ -1841,8 +1868,8 @@ class TenantLoginComponent {
1841
1868
  this.error = result.message || 'OAuth login failed';
1842
1869
  return;
1843
1870
  }
1844
- // Authentication successful, now handle tenant selection
1845
- await this.handlePostAuthFlow();
1871
+ // Authentication successful pass result so membership can be reused if present
1872
+ await this.handlePostAuthFlow(result);
1846
1873
  }
1847
1874
  catch (err) {
1848
1875
  this.error = err.message || 'An unexpected error occurred';
@@ -1851,7 +1878,7 @@ class TenantLoginComponent {
1851
1878
  this.loading = false;
1852
1879
  }
1853
1880
  }
1854
- async handlePostAuthFlow() {
1881
+ async handlePostAuthFlow(loginResult) {
1855
1882
  if (!this.showTenantSelector) {
1856
1883
  // Tenant selection is disabled, emit event immediately
1857
1884
  this.tenantSelected.emit({
@@ -1861,11 +1888,20 @@ class TenantLoginComponent {
1861
1888
  });
1862
1889
  return;
1863
1890
  }
1864
- // Fetch user's tenant memberships
1891
+ // Resolve memberships prefer data from login response to avoid extra API call
1865
1892
  this.loading = true;
1866
1893
  try {
1867
- const result = await this.auth.getTenantMemberships();
1868
- if (!result.memberships || result.memberships.length === 0) {
1894
+ let memberships;
1895
+ if (loginResult?.membership) {
1896
+ // Login response already included membership — use it directly
1897
+ memberships = [loginResult.membership];
1898
+ }
1899
+ else {
1900
+ // Fall back to fetching memberships from API (with platform_code param)
1901
+ const result = await this.auth.getTenantMemberships();
1902
+ memberships = result.memberships;
1903
+ }
1904
+ if (!memberships || memberships.length === 0) {
1869
1905
  // User has no tenants, prompt to create one
1870
1906
  this.error = 'You are not a member of any organization. Please create one.';
1871
1907
  if (this.allowTenantCreation) {
@@ -1873,7 +1909,7 @@ class TenantLoginComponent {
1873
1909
  }
1874
1910
  return;
1875
1911
  }
1876
- this.memberships = result.memberships;
1912
+ this.memberships = memberships;
1877
1913
  // Get user name if available
1878
1914
  const currentUser = this.auth.getCurrentUser();
1879
1915
  if (currentUser) {
@@ -3249,12 +3285,9 @@ class TenantRegisterComponent {
3249
3285
  tenantName: this.tenantName,
3250
3286
  provider: provider
3251
3287
  });
3252
- if (result.success && result.tenant && result.user) {
3288
+ if (result.success && result.user) {
3253
3289
  this.success = 'Organization created successfully!';
3254
- this.tenantCreated.emit({
3255
- tenant: result.tenant,
3256
- user: result.user
3257
- });
3290
+ this.tenantCreated.emit({ user: result.user });
3258
3291
  }
3259
3292
  else {
3260
3293
  this.error = result.message || 'Registration failed';
@@ -3284,12 +3317,9 @@ class TenantRegisterComponent {
3284
3317
  password: this.password,
3285
3318
  provider: 'emailPassword'
3286
3319
  });
3287
- if (result.success && result.tenant && result.user) {
3320
+ if (result.success && result.user) {
3288
3321
  this.success = 'Organization created successfully!';
3289
- this.tenantCreated.emit({
3290
- tenant: result.tenant,
3291
- user: result.user
3292
- });
3322
+ this.tenantCreated.emit({ user: result.user });
3293
3323
  }
3294
3324
  else {
3295
3325
  this.error = result.message || 'Registration failed';