@progalaxyelabs/ngx-stonescriptphp-client 1.16.0 → 1.17.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.
|
@@ -13,13 +13,6 @@ class MyEnvironmentModel {
|
|
|
13
13
|
* Used for multi-tenant authentication.
|
|
14
14
|
*/
|
|
15
15
|
platformCode = '';
|
|
16
|
-
/**
|
|
17
|
-
* Platform's own API base URL.
|
|
18
|
-
* Used for routes that go through the platform API proxy (e.g. register-tenant).
|
|
19
|
-
* Falls back to apiServer.host if not set.
|
|
20
|
-
* @example '//api.medstoreapp.in'
|
|
21
|
-
*/
|
|
22
|
-
apiUrl;
|
|
23
16
|
apiServer = { host: '' };
|
|
24
17
|
/**
|
|
25
18
|
* Files service server configuration.
|
|
@@ -27,6 +20,12 @@ class MyEnvironmentModel {
|
|
|
27
20
|
* @example { host: 'https://files.progalaxyelabs.com/api/' }
|
|
28
21
|
*/
|
|
29
22
|
filesServer;
|
|
23
|
+
/**
|
|
24
|
+
* Chat service server configuration.
|
|
25
|
+
* Used by Angular portals to establish authenticated WebSocket connections.
|
|
26
|
+
* @example { host: 'wss://chat.progalaxyelabs.com' }
|
|
27
|
+
*/
|
|
28
|
+
chatServer;
|
|
30
29
|
/**
|
|
31
30
|
* Authentication configuration.
|
|
32
31
|
* @default { mode: 'cookie', refreshEndpoint: '/auth/refresh', useCsrf: true }
|
|
@@ -204,9 +203,6 @@ class StoneScriptPHPAuth {
|
|
|
204
203
|
}
|
|
205
204
|
return this.config.host;
|
|
206
205
|
}
|
|
207
|
-
getPlatformApiUrl() {
|
|
208
|
-
return this.config.apiUrl || this.config.host;
|
|
209
|
-
}
|
|
210
206
|
getDefaultServer() {
|
|
211
207
|
if (!this.config.authServers)
|
|
212
208
|
return null;
|
|
@@ -514,82 +510,6 @@ class StoneScriptPHPAuth {
|
|
|
514
510
|
return [];
|
|
515
511
|
}
|
|
516
512
|
}
|
|
517
|
-
async registerTenant(data) {
|
|
518
|
-
if (data.provider !== 'emailPassword') {
|
|
519
|
-
return this.registerTenantWithOAuth(data.tenantName, data.provider);
|
|
520
|
-
}
|
|
521
|
-
try {
|
|
522
|
-
const apiUrl = this.getPlatformApiUrl();
|
|
523
|
-
const body = {
|
|
524
|
-
tenant_name: data.tenantName,
|
|
525
|
-
email: data.email ?? '',
|
|
526
|
-
password: data.password ?? '',
|
|
527
|
-
provider: 'emailPassword'
|
|
528
|
-
};
|
|
529
|
-
if (data.displayName)
|
|
530
|
-
body['display_name'] = data.displayName;
|
|
531
|
-
if (data.countryCode)
|
|
532
|
-
body['country_code'] = data.countryCode;
|
|
533
|
-
if (data.role)
|
|
534
|
-
body['role'] = data.role;
|
|
535
|
-
const response = await fetch(`${apiUrl}/auth/register-tenant`, {
|
|
536
|
-
method: 'POST',
|
|
537
|
-
headers: { 'Content-Type': 'application/json' },
|
|
538
|
-
credentials: 'include',
|
|
539
|
-
body: JSON.stringify(body)
|
|
540
|
-
});
|
|
541
|
-
const result = await response.json();
|
|
542
|
-
if (result?.status === 'ok' || result?.success === true) {
|
|
543
|
-
return { success: true };
|
|
544
|
-
}
|
|
545
|
-
return { success: false, message: result?.data?.message || result?.message || 'Registration failed' };
|
|
546
|
-
}
|
|
547
|
-
catch {
|
|
548
|
-
return { success: false, message: 'Network error. Please try again.' };
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
async registerTenantWithOAuth(tenantName, provider) {
|
|
552
|
-
return new Promise((resolve) => {
|
|
553
|
-
const width = 500, height = 600;
|
|
554
|
-
const left = (window.screen.width - width) / 2;
|
|
555
|
-
const top = (window.screen.height - height) / 2;
|
|
556
|
-
const accountsUrl = this.getAccountsUrl();
|
|
557
|
-
const oauthUrl = `${accountsUrl}/oauth/${provider}?` +
|
|
558
|
-
`platform=${this.config.platformCode}&mode=popup&action=register_tenant&` +
|
|
559
|
-
`tenant_name=${encodeURIComponent(tenantName)}`;
|
|
560
|
-
const popup = window.open(oauthUrl, `${provider}_register_tenant`, `width=${width},height=${height},left=${left},top=${top}`);
|
|
561
|
-
if (!popup) {
|
|
562
|
-
resolve({ success: false, message: 'Popup blocked. Please allow popups for this site.' });
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
const messageHandler = (event) => {
|
|
566
|
-
if (event.origin !== new URL(accountsUrl).origin)
|
|
567
|
-
return;
|
|
568
|
-
if (event.data.type === 'tenant_register_success') {
|
|
569
|
-
window.removeEventListener('message', messageHandler);
|
|
570
|
-
popup.close();
|
|
571
|
-
resolve({
|
|
572
|
-
success: true,
|
|
573
|
-
accessToken: event.data.access_token,
|
|
574
|
-
user: event.data.user ? this.normalizeUser(event.data.user) : undefined
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
else if (event.data.type === 'tenant_register_error') {
|
|
578
|
-
window.removeEventListener('message', messageHandler);
|
|
579
|
-
popup.close();
|
|
580
|
-
resolve({ success: false, message: event.data.message || 'Tenant registration failed' });
|
|
581
|
-
}
|
|
582
|
-
};
|
|
583
|
-
window.addEventListener('message', messageHandler);
|
|
584
|
-
const checkClosed = setInterval(() => {
|
|
585
|
-
if (popup.closed) {
|
|
586
|
-
clearInterval(checkClosed);
|
|
587
|
-
window.removeEventListener('message', messageHandler);
|
|
588
|
-
resolve({ success: false, message: 'Registration cancelled' });
|
|
589
|
-
}
|
|
590
|
-
}, 500);
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
513
|
async checkTenantSlugAvailable(slug) {
|
|
594
514
|
try {
|
|
595
515
|
const accountsUrl = this.getAccountsUrl();
|
|
@@ -612,49 +532,6 @@ class StoneScriptPHPAuth {
|
|
|
612
532
|
throw new Error('Failed to check onboarding status');
|
|
613
533
|
return response.json();
|
|
614
534
|
}
|
|
615
|
-
async completeTenantOnboarding(countryCode, tenantName, accessToken) {
|
|
616
|
-
const apiUrl = this.getPlatformApiUrl();
|
|
617
|
-
const response = await fetch(`${apiUrl}/auth/register-tenant`, {
|
|
618
|
-
method: 'POST',
|
|
619
|
-
headers: {
|
|
620
|
-
'Content-Type': 'application/json',
|
|
621
|
-
'Authorization': `Bearer ${accessToken}`
|
|
622
|
-
},
|
|
623
|
-
credentials: 'include',
|
|
624
|
-
body: JSON.stringify({
|
|
625
|
-
platform: this.config.platformCode,
|
|
626
|
-
tenant_name: tenantName,
|
|
627
|
-
country_code: countryCode,
|
|
628
|
-
provider: 'google',
|
|
629
|
-
oauth_token: accessToken
|
|
630
|
-
})
|
|
631
|
-
});
|
|
632
|
-
if (!response.ok) {
|
|
633
|
-
const errorData = await response.json();
|
|
634
|
-
throw new Error(errorData.message || 'Failed to create tenant');
|
|
635
|
-
}
|
|
636
|
-
return response.json();
|
|
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
|
-
}
|
|
658
535
|
async checkEmail(email) {
|
|
659
536
|
try {
|
|
660
537
|
const accountsUrl = this.getAccountsUrl();
|
|
@@ -717,8 +594,7 @@ function provideNgxStoneScriptPhpClient(environment, plugin) {
|
|
|
717
594
|
platformCode: environment.platformCode,
|
|
718
595
|
authServers: environment.authServers,
|
|
719
596
|
responseMap: environment.auth?.responseMap ?? environment.authResponseMap,
|
|
720
|
-
auth: environment.auth
|
|
721
|
-
apiUrl: environment.apiUrl
|
|
597
|
+
auth: environment.auth
|
|
722
598
|
});
|
|
723
599
|
return makeEnvironmentProviders([
|
|
724
600
|
{ provide: MyEnvironmentModel, useValue: environment },
|
|
@@ -1034,25 +910,6 @@ class AuthService {
|
|
|
1034
910
|
return this.userSubject.value;
|
|
1035
911
|
}
|
|
1036
912
|
// ── Multi-tenant operations ───────────────────────────────────────────────
|
|
1037
|
-
async registerTenant(data) {
|
|
1038
|
-
if (!this.plugin.registerTenant) {
|
|
1039
|
-
return { success: false, message: 'registerTenant not supported by the configured auth plugin' };
|
|
1040
|
-
}
|
|
1041
|
-
const registered = await this.plugin.registerTenant(data);
|
|
1042
|
-
if (!registered.success)
|
|
1043
|
-
return registered;
|
|
1044
|
-
// OAuth: token comes directly from the popup — store it and we're done.
|
|
1045
|
-
if (registered.accessToken) {
|
|
1046
|
-
this.storeAuthResult(registered);
|
|
1047
|
-
return registered;
|
|
1048
|
-
}
|
|
1049
|
-
// emailPassword: registration succeeded but no token yet.
|
|
1050
|
-
// Login via auth (SSO) to obtain tokens.
|
|
1051
|
-
if (data.provider === 'emailPassword' && data.email && data.password) {
|
|
1052
|
-
return await this.loginWithEmail(data.email, data.password);
|
|
1053
|
-
}
|
|
1054
|
-
return registered;
|
|
1055
|
-
}
|
|
1056
913
|
async getTenantMemberships(serverName) {
|
|
1057
914
|
if (!this.plugin.getTenantMemberships)
|
|
1058
915
|
return { memberships: [] };
|
|
@@ -1079,27 +936,6 @@ class AuthService {
|
|
|
1079
936
|
throw new Error('checkOnboardingStatus not supported');
|
|
1080
937
|
return this.plugin.checkOnboardingStatus(identityId);
|
|
1081
938
|
}
|
|
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
|
-
}
|
|
1093
|
-
async completeTenantOnboarding(countryCode, tenantName, serverName) {
|
|
1094
|
-
if (!this.plugin.completeTenantOnboarding)
|
|
1095
|
-
throw new Error('completeTenantOnboarding not supported');
|
|
1096
|
-
const result = await this.plugin.completeTenantOnboarding(countryCode, tenantName, this.tokens.getAccessToken());
|
|
1097
|
-
if (result?.access_token) {
|
|
1098
|
-
this.tokens.setAccessToken(result.access_token);
|
|
1099
|
-
this.signinStatus.setSigninStatus(true);
|
|
1100
|
-
}
|
|
1101
|
-
return result;
|
|
1102
|
-
}
|
|
1103
939
|
// ── Multi-server (delegated to plugin) ────────────────────────────────────
|
|
1104
940
|
getAvailableAuthServers() {
|
|
1105
941
|
return this.plugin.getAvailableServers?.() ?? [];
|
|
@@ -3213,7 +3049,7 @@ class TenantRegisterComponent {
|
|
|
3213
3049
|
tenantSlugLabel = 'Organization URL';
|
|
3214
3050
|
tenantSlugPlaceholder = 'organization-name';
|
|
3215
3051
|
urlPreviewEnabled = true;
|
|
3216
|
-
urlPreviewPrefix = '
|
|
3052
|
+
urlPreviewPrefix = 'yourapp.com/';
|
|
3217
3053
|
// User Labels
|
|
3218
3054
|
userSectionTitle = 'Your Information';
|
|
3219
3055
|
oauthDescription = 'Recommended: Sign up with your Google account';
|
|
@@ -3226,6 +3062,7 @@ class TenantRegisterComponent {
|
|
|
3226
3062
|
loginLinkAction = 'Sign in';
|
|
3227
3063
|
// Outputs
|
|
3228
3064
|
tenantCreated = new EventEmitter();
|
|
3065
|
+
registerRequested = new EventEmitter();
|
|
3229
3066
|
navigateToLogin = new EventEmitter();
|
|
3230
3067
|
// Form Fields
|
|
3231
3068
|
tenantName = '';
|
|
@@ -3348,64 +3185,49 @@ class TenantRegisterComponent {
|
|
|
3348
3185
|
}
|
|
3349
3186
|
return true;
|
|
3350
3187
|
}
|
|
3351
|
-
|
|
3188
|
+
onOAuthRegister(provider) {
|
|
3352
3189
|
if (!this.isFormValid()) {
|
|
3353
3190
|
this.error = 'Please complete the organization information';
|
|
3354
3191
|
return;
|
|
3355
3192
|
}
|
|
3356
|
-
this.loading = true;
|
|
3357
|
-
this.loadingText = `Signing up with ${provider}...`;
|
|
3358
3193
|
this.error = '';
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
if (result.success && result.user) {
|
|
3365
|
-
this.success = 'Organization created successfully!';
|
|
3366
|
-
this.tenantCreated.emit({ user: result.user });
|
|
3367
|
-
}
|
|
3368
|
-
else {
|
|
3369
|
-
this.error = result.message || 'Registration failed';
|
|
3370
|
-
}
|
|
3371
|
-
}
|
|
3372
|
-
catch (err) {
|
|
3373
|
-
this.error = err.message || 'An unexpected error occurred';
|
|
3374
|
-
}
|
|
3375
|
-
finally {
|
|
3376
|
-
this.loading = false;
|
|
3377
|
-
}
|
|
3194
|
+
this.registerRequested.emit({
|
|
3195
|
+
tenantName: this.tenantName,
|
|
3196
|
+
tenantSlug: this.tenantSlug,
|
|
3197
|
+
provider: provider
|
|
3198
|
+
});
|
|
3378
3199
|
}
|
|
3379
|
-
|
|
3200
|
+
onRegister() {
|
|
3380
3201
|
if (!this.isFormValid()) {
|
|
3381
3202
|
this.error = 'Please fill in all required fields correctly';
|
|
3382
3203
|
return;
|
|
3383
3204
|
}
|
|
3384
|
-
this.loading = true;
|
|
3385
|
-
this.loadingText = 'Creating your organization...';
|
|
3386
3205
|
this.error = '';
|
|
3387
3206
|
this.success = '';
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3207
|
+
this.registerRequested.emit({
|
|
3208
|
+
tenantName: this.tenantName,
|
|
3209
|
+
tenantSlug: this.tenantSlug,
|
|
3210
|
+
displayName: this.displayName,
|
|
3211
|
+
email: this.email,
|
|
3212
|
+
password: this.password,
|
|
3213
|
+
provider: 'emailPassword'
|
|
3214
|
+
});
|
|
3215
|
+
}
|
|
3216
|
+
/** Call from consuming component after handling registerRequested to show loading state */
|
|
3217
|
+
setLoading(loading, text) {
|
|
3218
|
+
this.loading = loading;
|
|
3219
|
+
if (text)
|
|
3220
|
+
this.loadingText = text;
|
|
3221
|
+
}
|
|
3222
|
+
/** Call from consuming component to show success/error after handling registerRequested */
|
|
3223
|
+
setResult(result) {
|
|
3224
|
+
this.loading = false;
|
|
3225
|
+
if (result.success && result.user) {
|
|
3226
|
+
this.success = 'Organization created successfully!';
|
|
3227
|
+
this.tenantCreated.emit({ user: result.user });
|
|
3406
3228
|
}
|
|
3407
|
-
|
|
3408
|
-
this.
|
|
3229
|
+
else if (!result.success) {
|
|
3230
|
+
this.error = result.message || 'Registration failed';
|
|
3409
3231
|
}
|
|
3410
3232
|
}
|
|
3411
3233
|
onLoginClick(event) {
|
|
@@ -3413,7 +3235,7 @@ class TenantRegisterComponent {
|
|
|
3413
3235
|
this.navigateToLogin.emit();
|
|
3414
3236
|
}
|
|
3415
3237
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TenantRegisterComponent, deps: [{ token: AuthService }, { token: ProviderRegistryService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3416
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: TenantRegisterComponent, isStandalone: true, selector: "lib-tenant-register", inputs: { title: "title", providers: "providers", requireTenantName: "requireTenantName", tenantSectionTitle: "tenantSectionTitle", tenantNameLabel: "tenantNameLabel", tenantNamePlaceholder: "tenantNamePlaceholder", tenantSlugLabel: "tenantSlugLabel", tenantSlugPlaceholder: "tenantSlugPlaceholder", urlPreviewEnabled: "urlPreviewEnabled", urlPreviewPrefix: "urlPreviewPrefix", userSectionTitle: "userSectionTitle", oauthDescription: "oauthDescription", ownershipTitle: "ownershipTitle", ownershipMessage: "ownershipMessage", submitButtonText: "submitButtonText", loginLinkText: "loginLinkText", loginLinkAction: "loginLinkAction" }, outputs: { tenantCreated: "tenantCreated", navigateToLogin: "navigateToLogin" }, ngImport: i0, template: `
|
|
3238
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: TenantRegisterComponent, isStandalone: true, selector: "lib-tenant-register", inputs: { title: "title", providers: "providers", requireTenantName: "requireTenantName", tenantSectionTitle: "tenantSectionTitle", tenantNameLabel: "tenantNameLabel", tenantNamePlaceholder: "tenantNamePlaceholder", tenantSlugLabel: "tenantSlugLabel", tenantSlugPlaceholder: "tenantSlugPlaceholder", urlPreviewEnabled: "urlPreviewEnabled", urlPreviewPrefix: "urlPreviewPrefix", userSectionTitle: "userSectionTitle", oauthDescription: "oauthDescription", ownershipTitle: "ownershipTitle", ownershipMessage: "ownershipMessage", submitButtonText: "submitButtonText", loginLinkText: "loginLinkText", loginLinkAction: "loginLinkAction" }, outputs: { tenantCreated: "tenantCreated", registerRequested: "registerRequested", navigateToLogin: "navigateToLogin" }, ngImport: i0, template: `
|
|
3417
3239
|
<div class="tenant-register-dialog">
|
|
3418
3240
|
<h2 class="register-title">{{ title }}</h2>
|
|
3419
3241
|
|
|
@@ -3870,6 +3692,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
3870
3692
|
type: Input
|
|
3871
3693
|
}], tenantCreated: [{
|
|
3872
3694
|
type: Output
|
|
3695
|
+
}], registerRequested: [{
|
|
3696
|
+
type: Output
|
|
3873
3697
|
}], navigateToLogin: [{
|
|
3874
3698
|
type: Output
|
|
3875
3699
|
}] } });
|
|
@@ -4051,7 +3875,7 @@ class TenantRegisterDialogComponent {
|
|
|
4051
3875
|
(navigateToLogin)="onNavigateToLogin()">
|
|
4052
3876
|
</lib-tenant-register>
|
|
4053
3877
|
</div>
|
|
4054
|
-
`, isInline: true, styles: [".dialog-wrapper{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TenantRegisterComponent, selector: "lib-tenant-register", inputs: ["title", "providers", "requireTenantName", "tenantSectionTitle", "tenantNameLabel", "tenantNamePlaceholder", "tenantSlugLabel", "tenantSlugPlaceholder", "urlPreviewEnabled", "urlPreviewPrefix", "userSectionTitle", "oauthDescription", "ownershipTitle", "ownershipMessage", "submitButtonText", "loginLinkText", "loginLinkAction"], outputs: ["tenantCreated", "navigateToLogin"] }] });
|
|
3878
|
+
`, isInline: true, styles: [".dialog-wrapper{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TenantRegisterComponent, selector: "lib-tenant-register", inputs: ["title", "providers", "requireTenantName", "tenantSectionTitle", "tenantNameLabel", "tenantNamePlaceholder", "tenantSlugLabel", "tenantSlugPlaceholder", "urlPreviewEnabled", "urlPreviewPrefix", "userSectionTitle", "oauthDescription", "ownershipTitle", "ownershipMessage", "submitButtonText", "loginLinkText", "loginLinkAction"], outputs: ["tenantCreated", "registerRequested", "navigateToLogin"] }] });
|
|
4055
3879
|
}
|
|
4056
3880
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TenantRegisterDialogComponent, decorators: [{
|
|
4057
3881
|
type: Component,
|