@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,
|
|
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
|
-
|
|
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}?
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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}?
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|