@progalaxyelabs/ngx-stonescriptphp-client 1.23.5 → 1.24.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.
@@ -175,6 +175,10 @@ class StoneScriptPHPAuth {
175
175
  else if (raw.id) {
176
176
  user.user_id = this.hashUUID(raw.id);
177
177
  }
178
+ // Populate role from raw data if available
179
+ if (raw.role) {
180
+ user.role = raw.role;
181
+ }
178
182
  return user;
179
183
  }
180
184
  hashUUID(uuid) {
@@ -261,7 +265,7 @@ class StoneScriptPHPAuth {
261
265
  method: 'POST',
262
266
  headers: { 'Content-Type': 'application/json' },
263
267
  credentials: 'include',
264
- body: JSON.stringify({ email, password, platform: this.config.platformCode })
268
+ body: JSON.stringify({ email, password, platform_code: this.config.platformCode })
265
269
  });
266
270
  const data = await response.json();
267
271
  if (this.isAuthSuccess(data)) {
@@ -290,7 +294,7 @@ class StoneScriptPHPAuth {
290
294
  email,
291
295
  password,
292
296
  display_name: displayName,
293
- platform: this.config.platformCode
297
+ platform_code: this.config.platformCode
294
298
  })
295
299
  });
296
300
  const data = await response.json();
@@ -414,7 +418,7 @@ class StoneScriptPHPAuth {
414
418
  const left = (window.screen.width - width) / 2;
415
419
  const top = (window.screen.height - height) / 2;
416
420
  const accountsUrl = this.getAccountsUrl();
417
- const oauthUrl = `${accountsUrl}/oauth/${provider}?platform=${this.config.platformCode}&mode=popup`;
421
+ const oauthUrl = `${accountsUrl}/oauth/${provider}?platform_code=${this.config.platformCode}&mode=popup`;
418
422
  const popup = window.open(oauthUrl, `${provider}_login`, `width=${width},height=${height},left=${left},top=${top}`);
419
423
  if (!popup) {
420
424
  resolve({ success: false, message: 'Popup blocked. Please allow popups for this site.' });
@@ -633,7 +637,7 @@ class ProgalaxyElabsAuth {
633
637
  const response = await fetch(`${this.host}/api/auth/login`, {
634
638
  method: 'POST',
635
639
  headers: { 'Content-Type': 'application/json' },
636
- body: JSON.stringify({ email, password, platform: this.config.platformCode })
640
+ body: JSON.stringify({ email, password, platform_code: this.config.platformCode })
637
641
  });
638
642
  const data = await response.json();
639
643
  if (!response.ok) {
@@ -654,7 +658,7 @@ class ProgalaxyElabsAuth {
654
658
  email,
655
659
  password,
656
660
  display_name: displayName,
657
- platform: this.config.platformCode
661
+ platform_code: this.config.platformCode
658
662
  })
659
663
  });
660
664
  const data = await response.json();
@@ -722,7 +726,7 @@ class ProgalaxyElabsAuth {
722
726
  success: true,
723
727
  accessToken: data.access_token,
724
728
  refreshToken: data.refresh_token,
725
- user: this.toUser(data.identity),
729
+ user: this.toUser(data.identity, data.membership?.role),
726
730
  membership: this.toMembership(data.membership),
727
731
  };
728
732
  }
@@ -841,7 +845,7 @@ class ProgalaxyElabsAuth {
841
845
  headers: { 'Content-Type': 'application/json' },
842
846
  body: JSON.stringify({
843
847
  verified_token: verifiedToken,
844
- platform: this.config.platformCode
848
+ platform_code: this.config.platformCode
845
849
  })
846
850
  });
847
851
  // 404 means no identity found — caller should show registration form
@@ -866,7 +870,7 @@ class ProgalaxyElabsAuth {
866
870
  body: JSON.stringify({
867
871
  verified_token: verifiedToken,
868
872
  display_name: displayName,
869
- platform: this.config.platformCode
873
+ platform_code: this.config.platformCode
870
874
  })
871
875
  });
872
876
  const data = await response.json();
@@ -885,7 +889,7 @@ class ProgalaxyElabsAuth {
885
889
  const width = 500, height = 600;
886
890
  const left = (window.screen.width - width) / 2;
887
891
  const top = (window.screen.height - height) / 2;
888
- const oauthUrl = `${this.host}/oauth/${provider}?platform=${this.config.platformCode}&mode=popup`;
892
+ const oauthUrl = `${this.host}/oauth/${provider}?platform_code=${this.config.platformCode}&mode=popup`;
889
893
  const popup = window.open(oauthUrl, `${provider}_login`, `width=${width},height=${height},left=${left},top=${top}`);
890
894
  if (!popup) {
891
895
  resolve({ success: false, message: 'Popup blocked. Please allow popups for this site.' });
@@ -971,20 +975,25 @@ class ProgalaxyElabsAuth {
971
975
  success: true,
972
976
  accessToken: data.access_token,
973
977
  refreshToken: data.refresh_token,
974
- user: this.toUser(data.identity),
978
+ user: this.toUser(data.identity, data.membership?.role),
975
979
  membership: this.toMembership(data.membership),
976
980
  };
977
981
  }
978
- toUser(raw) {
982
+ toUser(raw, role) {
979
983
  if (!raw)
980
984
  return undefined;
981
- return {
985
+ const user = {
982
986
  email: raw.email ?? '',
983
987
  phone: raw.phone,
984
988
  display_name: raw.display_name ?? raw.email?.split('@')[0] ?? '',
985
989
  photo_url: raw.photo_url ?? raw.picture,
986
990
  is_email_verified: raw.is_email_verified ?? false
987
991
  };
992
+ // Populate role: prefer explicit param, then raw.role, then raw.membership?.role
993
+ const resolvedRole = role ?? raw.role ?? raw.membership?.role;
994
+ if (resolvedRole)
995
+ user.role = resolvedRole;
996
+ return user;
988
997
  }
989
998
  toMembership(raw) {
990
999
  return {
@@ -1108,6 +1117,31 @@ class TokenService {
1108
1117
  const token = this.getAccessToken();
1109
1118
  return token !== null && token !== '';
1110
1119
  }
1120
+ /**
1121
+ * Decode the payload of a JWT without verifying the signature.
1122
+ * Returns the parsed claims object, or null if the token is invalid/missing.
1123
+ *
1124
+ * Usage: const claims = tokenService.decodeJwtPayload(token);
1125
+ * const role = claims?.role;
1126
+ */
1127
+ decodeJwtPayload(token) {
1128
+ const jwt = token ?? this.getAccessToken();
1129
+ if (!jwt)
1130
+ return null;
1131
+ try {
1132
+ const parts = jwt.split('.');
1133
+ if (parts.length !== 3)
1134
+ return null;
1135
+ // Base64url → Base64 → JSON
1136
+ const base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');
1137
+ const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);
1138
+ const json = atob(padded);
1139
+ return JSON.parse(json);
1140
+ }
1141
+ catch {
1142
+ return null;
1143
+ }
1144
+ }
1111
1145
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1112
1146
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TokenService, providedIn: 'root' });
1113
1147
  }
@@ -1213,10 +1247,28 @@ class AuthService {
1213
1247
  this.tokens.setAccessToken(result.accessToken);
1214
1248
  if (result.refreshToken)
1215
1249
  this.tokens.setRefreshToken(result.refreshToken);
1216
- if (result.user)
1217
- this.updateUser(result.user);
1250
+ if (result.user) {
1251
+ // Enrich user with role from JWT claims if not already set
1252
+ const user = result.user.role
1253
+ ? result.user
1254
+ : this.enrichUserWithJwtRole(result.user, result.accessToken);
1255
+ this.updateUser(user);
1256
+ }
1218
1257
  this.signinStatus.setSigninStatus(true);
1219
1258
  }
1259
+ /**
1260
+ * Decode the access token and attach the `role` claim to the user object.
1261
+ * Falls back to role from the membership field in the AuthResult if no JWT role found.
1262
+ */
1263
+ enrichUserWithJwtRole(user, accessToken) {
1264
+ if (accessToken) {
1265
+ const claims = this.tokens.decodeJwtPayload(accessToken);
1266
+ if (claims?.role) {
1267
+ return { ...user, role: claims.role };
1268
+ }
1269
+ }
1270
+ return user;
1271
+ }
1220
1272
  // ── Core auth operations ──────────────────────────────────────────────────
1221
1273
  async loginWithEmail(email, password) {
1222
1274
  const result = await this.plugin.login(email, password);
@@ -1269,14 +1321,22 @@ class AuthService {
1269
1321
  }
1270
1322
  async checkSession(serverName) {
1271
1323
  if (this.tokens.hasValidAccessToken()) {
1324
+ // If we already have a stored user, update their role from the current JWT
1325
+ const storedUser = this.getCurrentUser();
1326
+ if (storedUser && !storedUser.role) {
1327
+ const enriched = this.enrichUserWithJwtRole(storedUser);
1328
+ if (enriched.role)
1329
+ this.updateUser(enriched);
1330
+ }
1272
1331
  this.signinStatus.setSigninStatus(true);
1273
1332
  return true;
1274
1333
  }
1275
1334
  const result = await this.plugin.checkSession();
1276
1335
  if (result.success && result.accessToken) {
1277
1336
  this.tokens.setAccessToken(result.accessToken);
1278
- if (result.user)
1279
- this.updateUser(result.user);
1337
+ if (result.user) {
1338
+ this.updateUser(this.enrichUserWithJwtRole(result.user, result.accessToken));
1339
+ }
1280
1340
  this.signinStatus.setSigninStatus(true);
1281
1341
  return true;
1282
1342
  }