@progalaxyelabs/ngx-stonescriptphp-client 1.16.1 → 1.18.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.
|
@@ -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.
|
|
@@ -210,9 +203,6 @@ class StoneScriptPHPAuth {
|
|
|
210
203
|
}
|
|
211
204
|
return this.config.host;
|
|
212
205
|
}
|
|
213
|
-
getPlatformApiUrl() {
|
|
214
|
-
return this.config.apiUrl || this.config.host;
|
|
215
|
-
}
|
|
216
206
|
getDefaultServer() {
|
|
217
207
|
if (!this.config.authServers)
|
|
218
208
|
return null;
|
|
@@ -520,82 +510,6 @@ class StoneScriptPHPAuth {
|
|
|
520
510
|
return [];
|
|
521
511
|
}
|
|
522
512
|
}
|
|
523
|
-
async registerTenant(data) {
|
|
524
|
-
if (data.provider !== 'emailPassword') {
|
|
525
|
-
return this.registerTenantWithOAuth(data.tenantName, data.provider);
|
|
526
|
-
}
|
|
527
|
-
try {
|
|
528
|
-
const apiUrl = this.getPlatformApiUrl();
|
|
529
|
-
const body = {
|
|
530
|
-
tenant_name: data.tenantName,
|
|
531
|
-
email: data.email ?? '',
|
|
532
|
-
password: data.password ?? '',
|
|
533
|
-
provider: 'emailPassword'
|
|
534
|
-
};
|
|
535
|
-
if (data.displayName)
|
|
536
|
-
body['display_name'] = data.displayName;
|
|
537
|
-
if (data.countryCode)
|
|
538
|
-
body['country_code'] = data.countryCode;
|
|
539
|
-
if (data.role)
|
|
540
|
-
body['role'] = data.role;
|
|
541
|
-
const response = await fetch(`${apiUrl}/auth/register-tenant`, {
|
|
542
|
-
method: 'POST',
|
|
543
|
-
headers: { 'Content-Type': 'application/json' },
|
|
544
|
-
credentials: 'include',
|
|
545
|
-
body: JSON.stringify(body)
|
|
546
|
-
});
|
|
547
|
-
const result = await response.json();
|
|
548
|
-
if (result?.status === 'ok' || result?.success === true) {
|
|
549
|
-
return { success: true };
|
|
550
|
-
}
|
|
551
|
-
return { success: false, message: result?.data?.message || result?.message || 'Registration failed' };
|
|
552
|
-
}
|
|
553
|
-
catch {
|
|
554
|
-
return { success: false, message: 'Network error. Please try again.' };
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
async registerTenantWithOAuth(tenantName, provider) {
|
|
558
|
-
return new Promise((resolve) => {
|
|
559
|
-
const width = 500, height = 600;
|
|
560
|
-
const left = (window.screen.width - width) / 2;
|
|
561
|
-
const top = (window.screen.height - height) / 2;
|
|
562
|
-
const accountsUrl = this.getAccountsUrl();
|
|
563
|
-
const oauthUrl = `${accountsUrl}/oauth/${provider}?` +
|
|
564
|
-
`platform=${this.config.platformCode}&mode=popup&action=register_tenant&` +
|
|
565
|
-
`tenant_name=${encodeURIComponent(tenantName)}`;
|
|
566
|
-
const popup = window.open(oauthUrl, `${provider}_register_tenant`, `width=${width},height=${height},left=${left},top=${top}`);
|
|
567
|
-
if (!popup) {
|
|
568
|
-
resolve({ success: false, message: 'Popup blocked. Please allow popups for this site.' });
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
const messageHandler = (event) => {
|
|
572
|
-
if (event.origin !== new URL(accountsUrl).origin)
|
|
573
|
-
return;
|
|
574
|
-
if (event.data.type === 'tenant_register_success') {
|
|
575
|
-
window.removeEventListener('message', messageHandler);
|
|
576
|
-
popup.close();
|
|
577
|
-
resolve({
|
|
578
|
-
success: true,
|
|
579
|
-
accessToken: event.data.access_token,
|
|
580
|
-
user: event.data.user ? this.normalizeUser(event.data.user) : undefined
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
else if (event.data.type === 'tenant_register_error') {
|
|
584
|
-
window.removeEventListener('message', messageHandler);
|
|
585
|
-
popup.close();
|
|
586
|
-
resolve({ success: false, message: event.data.message || 'Tenant registration failed' });
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
|
-
window.addEventListener('message', messageHandler);
|
|
590
|
-
const checkClosed = setInterval(() => {
|
|
591
|
-
if (popup.closed) {
|
|
592
|
-
clearInterval(checkClosed);
|
|
593
|
-
window.removeEventListener('message', messageHandler);
|
|
594
|
-
resolve({ success: false, message: 'Registration cancelled' });
|
|
595
|
-
}
|
|
596
|
-
}, 500);
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
513
|
async checkTenantSlugAvailable(slug) {
|
|
600
514
|
try {
|
|
601
515
|
const accountsUrl = this.getAccountsUrl();
|
|
@@ -618,49 +532,6 @@ class StoneScriptPHPAuth {
|
|
|
618
532
|
throw new Error('Failed to check onboarding status');
|
|
619
533
|
return response.json();
|
|
620
534
|
}
|
|
621
|
-
async completeTenantOnboarding(countryCode, tenantName, accessToken) {
|
|
622
|
-
const apiUrl = this.getPlatformApiUrl();
|
|
623
|
-
const response = await fetch(`${apiUrl}/auth/register-tenant`, {
|
|
624
|
-
method: 'POST',
|
|
625
|
-
headers: {
|
|
626
|
-
'Content-Type': 'application/json',
|
|
627
|
-
'Authorization': `Bearer ${accessToken}`
|
|
628
|
-
},
|
|
629
|
-
credentials: 'include',
|
|
630
|
-
body: JSON.stringify({
|
|
631
|
-
platform: this.config.platformCode,
|
|
632
|
-
tenant_name: tenantName,
|
|
633
|
-
country_code: countryCode,
|
|
634
|
-
provider: 'google',
|
|
635
|
-
oauth_token: accessToken
|
|
636
|
-
})
|
|
637
|
-
});
|
|
638
|
-
if (!response.ok) {
|
|
639
|
-
const errorData = await response.json();
|
|
640
|
-
throw new Error(errorData.message || 'Failed to create tenant');
|
|
641
|
-
}
|
|
642
|
-
return response.json();
|
|
643
|
-
}
|
|
644
|
-
async provisionTenant(storeName, countryCode, accessToken) {
|
|
645
|
-
const apiUrl = this.getPlatformApiUrl();
|
|
646
|
-
const response = await fetch(`${apiUrl}/auth/provision-tenant`, {
|
|
647
|
-
method: 'POST',
|
|
648
|
-
headers: {
|
|
649
|
-
'Content-Type': 'application/json',
|
|
650
|
-
'Authorization': `Bearer ${accessToken}`
|
|
651
|
-
},
|
|
652
|
-
credentials: 'include',
|
|
653
|
-
body: JSON.stringify({
|
|
654
|
-
store_name: storeName,
|
|
655
|
-
country_code: countryCode,
|
|
656
|
-
})
|
|
657
|
-
});
|
|
658
|
-
if (!response.ok) {
|
|
659
|
-
const errorData = await response.json();
|
|
660
|
-
throw new Error(errorData.message || 'Failed to provision tenant');
|
|
661
|
-
}
|
|
662
|
-
return response.json();
|
|
663
|
-
}
|
|
664
535
|
async checkEmail(email) {
|
|
665
536
|
try {
|
|
666
537
|
const accountsUrl = this.getAccountsUrl();
|
|
@@ -723,8 +594,7 @@ function provideNgxStoneScriptPhpClient(environment, plugin) {
|
|
|
723
594
|
platformCode: environment.platformCode,
|
|
724
595
|
authServers: environment.authServers,
|
|
725
596
|
responseMap: environment.auth?.responseMap ?? environment.authResponseMap,
|
|
726
|
-
auth: environment.auth
|
|
727
|
-
apiUrl: environment.apiUrl
|
|
597
|
+
auth: environment.auth
|
|
728
598
|
});
|
|
729
599
|
return makeEnvironmentProviders([
|
|
730
600
|
{ provide: MyEnvironmentModel, useValue: environment },
|
|
@@ -732,6 +602,289 @@ function provideNgxStoneScriptPhpClient(environment, plugin) {
|
|
|
732
602
|
]);
|
|
733
603
|
}
|
|
734
604
|
|
|
605
|
+
/**
|
|
606
|
+
* Auth plugin for progalaxyelabs-auth (Rust/Axum).
|
|
607
|
+
*
|
|
608
|
+
* Speaks the Rust auth server's native format:
|
|
609
|
+
* - Login: { access_token, refresh_token, identity, membership, ... }
|
|
610
|
+
* - Tenant selection: { requires_tenant_selection, selection_token, memberships }
|
|
611
|
+
* - New identity: { access_token, identity, is_new_identity, memberships:[] }
|
|
612
|
+
* - select-tenant: Bearer header + { tenant_id } body
|
|
613
|
+
* - refresh: { access_token, refresh_token } body mode
|
|
614
|
+
*/
|
|
615
|
+
class ProgalaxyElabsAuth {
|
|
616
|
+
config;
|
|
617
|
+
constructor(config) {
|
|
618
|
+
this.config = config;
|
|
619
|
+
}
|
|
620
|
+
get host() {
|
|
621
|
+
return this.config.host;
|
|
622
|
+
}
|
|
623
|
+
// -- Login ----------------------------------------------------------------
|
|
624
|
+
async login(email, password) {
|
|
625
|
+
try {
|
|
626
|
+
const response = await fetch(`${this.host}/api/auth/login`, {
|
|
627
|
+
method: 'POST',
|
|
628
|
+
headers: { 'Content-Type': 'application/json' },
|
|
629
|
+
body: JSON.stringify({ email, password, platform: this.config.platformCode })
|
|
630
|
+
});
|
|
631
|
+
const data = await response.json();
|
|
632
|
+
if (!response.ok) {
|
|
633
|
+
return { success: false, message: data.error || data.message || 'Login failed' };
|
|
634
|
+
}
|
|
635
|
+
return this.handleLoginResponse(data);
|
|
636
|
+
}
|
|
637
|
+
catch {
|
|
638
|
+
return { success: false, message: 'Network error. Please try again.' };
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
async register(email, password, displayName) {
|
|
642
|
+
try {
|
|
643
|
+
const response = await fetch(`${this.host}/api/auth/register`, {
|
|
644
|
+
method: 'POST',
|
|
645
|
+
headers: { 'Content-Type': 'application/json' },
|
|
646
|
+
body: JSON.stringify({
|
|
647
|
+
email,
|
|
648
|
+
password,
|
|
649
|
+
display_name: displayName,
|
|
650
|
+
platform: this.config.platformCode
|
|
651
|
+
})
|
|
652
|
+
});
|
|
653
|
+
const data = await response.json();
|
|
654
|
+
if (!response.ok) {
|
|
655
|
+
return { success: false, message: data.error || data.message || 'Registration failed' };
|
|
656
|
+
}
|
|
657
|
+
return this.handleLoginResponse(data);
|
|
658
|
+
}
|
|
659
|
+
catch {
|
|
660
|
+
return { success: false, message: 'Network error. Please try again.' };
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
// -- Logout ---------------------------------------------------------------
|
|
664
|
+
async logout(refreshToken) {
|
|
665
|
+
try {
|
|
666
|
+
await fetch(`${this.host}/api/auth/logout`, {
|
|
667
|
+
method: 'POST',
|
|
668
|
+
headers: { 'Content-Type': 'application/json' },
|
|
669
|
+
body: JSON.stringify({ refresh_token: refreshToken })
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
catch { /* ignore */ }
|
|
673
|
+
}
|
|
674
|
+
// -- Session & Refresh ----------------------------------------------------
|
|
675
|
+
async checkSession() {
|
|
676
|
+
return { success: false };
|
|
677
|
+
}
|
|
678
|
+
async refresh(accessToken, refreshToken) {
|
|
679
|
+
if (!refreshToken)
|
|
680
|
+
return null;
|
|
681
|
+
try {
|
|
682
|
+
const response = await fetch(`${this.host}/api/auth/refresh`, {
|
|
683
|
+
method: 'POST',
|
|
684
|
+
headers: { 'Content-Type': 'application/json' },
|
|
685
|
+
body: JSON.stringify({ access_token: accessToken, refresh_token: refreshToken })
|
|
686
|
+
});
|
|
687
|
+
if (!response.ok)
|
|
688
|
+
return null;
|
|
689
|
+
const data = await response.json();
|
|
690
|
+
// Refresh can also return tenant_selection if memberships changed
|
|
691
|
+
if (data.requires_tenant_selection)
|
|
692
|
+
return null;
|
|
693
|
+
return data.access_token ?? null;
|
|
694
|
+
}
|
|
695
|
+
catch {
|
|
696
|
+
return null;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// -- Tenant operations ----------------------------------------------------
|
|
700
|
+
async selectTenant(tenantId, selectionToken) {
|
|
701
|
+
try {
|
|
702
|
+
const response = await fetch(`${this.host}/api/auth/select-tenant`, {
|
|
703
|
+
method: 'POST',
|
|
704
|
+
headers: {
|
|
705
|
+
'Authorization': `Bearer ${selectionToken}`,
|
|
706
|
+
'Content-Type': 'application/json'
|
|
707
|
+
},
|
|
708
|
+
body: JSON.stringify({ tenant_id: tenantId })
|
|
709
|
+
});
|
|
710
|
+
const data = await response.json();
|
|
711
|
+
if (!response.ok) {
|
|
712
|
+
return { success: false, message: data.error || data.message || 'Tenant selection failed' };
|
|
713
|
+
}
|
|
714
|
+
return {
|
|
715
|
+
success: true,
|
|
716
|
+
accessToken: data.access_token,
|
|
717
|
+
refreshToken: data.refresh_token,
|
|
718
|
+
user: this.toUser(data.identity),
|
|
719
|
+
membership: this.toMembership(data.membership),
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
catch {
|
|
723
|
+
return { success: false, message: 'Network error. Please try again.' };
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
async getTenantMemberships(accessToken) {
|
|
727
|
+
try {
|
|
728
|
+
const platformCode = encodeURIComponent(this.config.platformCode);
|
|
729
|
+
const response = await fetch(`${this.host}/api/auth/memberships?platform_code=${platformCode}`, {
|
|
730
|
+
method: 'GET',
|
|
731
|
+
headers: { 'Authorization': `Bearer ${accessToken}` }
|
|
732
|
+
});
|
|
733
|
+
if (!response.ok)
|
|
734
|
+
return [];
|
|
735
|
+
const data = await response.json();
|
|
736
|
+
return (data.memberships || []).map((m) => this.toMembership(m));
|
|
737
|
+
}
|
|
738
|
+
catch {
|
|
739
|
+
return [];
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
async checkTenantSlugAvailable(slug) {
|
|
743
|
+
try {
|
|
744
|
+
const response = await fetch(`${this.host}/api/auth/check-tenant-slug/${slug}`);
|
|
745
|
+
const data = await response.json();
|
|
746
|
+
return { available: data.available || false, suggestion: data.suggestion };
|
|
747
|
+
}
|
|
748
|
+
catch {
|
|
749
|
+
return { available: true };
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
async checkOnboardingStatus(identityId, platformCode) {
|
|
753
|
+
const platform = platformCode ?? this.config.platformCode;
|
|
754
|
+
const response = await fetch(`${this.host}/api/auth/onboarding/status?platform_code=${platform}&identity_id=${identityId}`);
|
|
755
|
+
if (!response.ok)
|
|
756
|
+
throw new Error('Failed to check onboarding status');
|
|
757
|
+
return response.json();
|
|
758
|
+
}
|
|
759
|
+
async checkEmail(email) {
|
|
760
|
+
try {
|
|
761
|
+
const response = await fetch(`${this.host}/api/auth/check-email`, {
|
|
762
|
+
method: 'POST',
|
|
763
|
+
headers: { 'Content-Type': 'application/json' },
|
|
764
|
+
body: JSON.stringify({ email })
|
|
765
|
+
});
|
|
766
|
+
const data = await response.json();
|
|
767
|
+
return { exists: data.exists, user: data.user };
|
|
768
|
+
}
|
|
769
|
+
catch {
|
|
770
|
+
return { exists: false };
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
// -- OAuth ----------------------------------------------------------------
|
|
774
|
+
async loginWithProvider(provider) {
|
|
775
|
+
return new Promise((resolve) => {
|
|
776
|
+
const width = 500, height = 600;
|
|
777
|
+
const left = (window.screen.width - width) / 2;
|
|
778
|
+
const top = (window.screen.height - height) / 2;
|
|
779
|
+
const oauthUrl = `${this.host}/oauth/${provider}?platform=${this.config.platformCode}&mode=popup`;
|
|
780
|
+
const popup = window.open(oauthUrl, `${provider}_login`, `width=${width},height=${height},left=${left},top=${top}`);
|
|
781
|
+
if (!popup) {
|
|
782
|
+
resolve({ success: false, message: 'Popup blocked. Please allow popups for this site.' });
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
const cleanup = () => {
|
|
786
|
+
window.removeEventListener('message', messageHandler);
|
|
787
|
+
clearInterval(checkClosed);
|
|
788
|
+
if (popup && !popup.closed)
|
|
789
|
+
popup.close();
|
|
790
|
+
};
|
|
791
|
+
const messageHandler = (event) => {
|
|
792
|
+
if (event.origin !== new URL(this.host).origin)
|
|
793
|
+
return;
|
|
794
|
+
cleanup();
|
|
795
|
+
if (event.data.type === 'oauth_success') {
|
|
796
|
+
resolve({
|
|
797
|
+
success: true,
|
|
798
|
+
accessToken: event.data.access_token,
|
|
799
|
+
refreshToken: event.data.refresh_token,
|
|
800
|
+
user: this.toUser(event.data.user || event.data.identity),
|
|
801
|
+
membership: event.data.membership ? this.toMembership(event.data.membership) : undefined,
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
else if (event.data.type === 'oauth_tenant_selection') {
|
|
805
|
+
resolve({
|
|
806
|
+
success: true,
|
|
807
|
+
accessToken: event.data.selection_token,
|
|
808
|
+
memberships: (event.data.memberships || []).map((m) => this.toMembership(m)),
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
else if (event.data.type === 'oauth_new_identity') {
|
|
812
|
+
resolve({
|
|
813
|
+
success: true,
|
|
814
|
+
accessToken: event.data.access_token,
|
|
815
|
+
refreshToken: event.data.refresh_token,
|
|
816
|
+
isNewIdentity: true,
|
|
817
|
+
authMethod: event.data.auth_method,
|
|
818
|
+
oauthProvider: event.data.oauth_provider,
|
|
819
|
+
identity: event.data.identity,
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
else if (event.data.type === 'oauth_error') {
|
|
823
|
+
resolve({ success: false, message: event.data.message || 'OAuth login failed' });
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
window.addEventListener('message', messageHandler);
|
|
827
|
+
const checkClosed = setInterval(() => {
|
|
828
|
+
if (popup.closed) {
|
|
829
|
+
clearInterval(checkClosed);
|
|
830
|
+
window.removeEventListener('message', messageHandler);
|
|
831
|
+
resolve({ success: false, message: 'Login cancelled' });
|
|
832
|
+
}
|
|
833
|
+
}, 500);
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
// -- Internal helpers -----------------------------------------------------
|
|
837
|
+
handleLoginResponse(data) {
|
|
838
|
+
// New identity — needs onboarding
|
|
839
|
+
if (data.is_new_identity) {
|
|
840
|
+
return {
|
|
841
|
+
success: true,
|
|
842
|
+
accessToken: data.access_token,
|
|
843
|
+
refreshToken: data.refresh_token,
|
|
844
|
+
isNewIdentity: true,
|
|
845
|
+
authMethod: data.auth_method,
|
|
846
|
+
oauthProvider: data.oauth_provider,
|
|
847
|
+
identity: data.identity,
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
// Multi-tenant selection required
|
|
851
|
+
if (data.requires_tenant_selection) {
|
|
852
|
+
return {
|
|
853
|
+
success: true,
|
|
854
|
+
accessToken: data.selection_token,
|
|
855
|
+
memberships: (data.memberships || []).map((m) => this.toMembership(m)),
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
// Standard success (single tenant auto-selected or tenant specified)
|
|
859
|
+
return {
|
|
860
|
+
success: true,
|
|
861
|
+
accessToken: data.access_token,
|
|
862
|
+
refreshToken: data.refresh_token,
|
|
863
|
+
user: this.toUser(data.identity),
|
|
864
|
+
membership: this.toMembership(data.membership),
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
toUser(raw) {
|
|
868
|
+
if (!raw)
|
|
869
|
+
return undefined;
|
|
870
|
+
return {
|
|
871
|
+
email: raw.email,
|
|
872
|
+
display_name: raw.display_name ?? raw.email?.split('@')[0] ?? '',
|
|
873
|
+
photo_url: raw.photo_url ?? raw.picture,
|
|
874
|
+
is_email_verified: raw.is_email_verified ?? false
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
toMembership(raw) {
|
|
878
|
+
return {
|
|
879
|
+
tenant_id: raw.tenant_id,
|
|
880
|
+
slug: raw.tenant_slug ?? raw.slug ?? '',
|
|
881
|
+
name: raw.tenant_name ?? raw.name ?? '',
|
|
882
|
+
role: raw.role ?? '',
|
|
883
|
+
status: raw.status ?? 'active',
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
735
888
|
class ApiResponse {
|
|
736
889
|
status;
|
|
737
890
|
data;
|
|
@@ -1040,25 +1193,6 @@ class AuthService {
|
|
|
1040
1193
|
return this.userSubject.value;
|
|
1041
1194
|
}
|
|
1042
1195
|
// ── Multi-tenant operations ───────────────────────────────────────────────
|
|
1043
|
-
async registerTenant(data) {
|
|
1044
|
-
if (!this.plugin.registerTenant) {
|
|
1045
|
-
return { success: false, message: 'registerTenant not supported by the configured auth plugin' };
|
|
1046
|
-
}
|
|
1047
|
-
const registered = await this.plugin.registerTenant(data);
|
|
1048
|
-
if (!registered.success)
|
|
1049
|
-
return registered;
|
|
1050
|
-
// OAuth: token comes directly from the popup — store it and we're done.
|
|
1051
|
-
if (registered.accessToken) {
|
|
1052
|
-
this.storeAuthResult(registered);
|
|
1053
|
-
return registered;
|
|
1054
|
-
}
|
|
1055
|
-
// emailPassword: registration succeeded but no token yet.
|
|
1056
|
-
// Login via auth (SSO) to obtain tokens.
|
|
1057
|
-
if (data.provider === 'emailPassword' && data.email && data.password) {
|
|
1058
|
-
return await this.loginWithEmail(data.email, data.password);
|
|
1059
|
-
}
|
|
1060
|
-
return registered;
|
|
1061
|
-
}
|
|
1062
1196
|
async getTenantMemberships(serverName) {
|
|
1063
1197
|
if (!this.plugin.getTenantMemberships)
|
|
1064
1198
|
return { memberships: [] };
|
|
@@ -1085,27 +1219,6 @@ class AuthService {
|
|
|
1085
1219
|
throw new Error('checkOnboardingStatus not supported');
|
|
1086
1220
|
return this.plugin.checkOnboardingStatus(identityId);
|
|
1087
1221
|
}
|
|
1088
|
-
async provisionTenant(storeName, countryCode = 'IN') {
|
|
1089
|
-
if (!this.plugin.provisionTenant) {
|
|
1090
|
-
throw new Error('provisionTenant not supported by the configured auth plugin');
|
|
1091
|
-
}
|
|
1092
|
-
const result = await this.plugin.provisionTenant(storeName, countryCode, this.tokens.getAccessToken());
|
|
1093
|
-
if (result?.access_token) {
|
|
1094
|
-
this.tokens.setAccessToken(result.access_token);
|
|
1095
|
-
this.signinStatus.setSigninStatus(true);
|
|
1096
|
-
}
|
|
1097
|
-
return result;
|
|
1098
|
-
}
|
|
1099
|
-
async completeTenantOnboarding(countryCode, tenantName, serverName) {
|
|
1100
|
-
if (!this.plugin.completeTenantOnboarding)
|
|
1101
|
-
throw new Error('completeTenantOnboarding not supported');
|
|
1102
|
-
const result = await this.plugin.completeTenantOnboarding(countryCode, tenantName, this.tokens.getAccessToken());
|
|
1103
|
-
if (result?.access_token) {
|
|
1104
|
-
this.tokens.setAccessToken(result.access_token);
|
|
1105
|
-
this.signinStatus.setSigninStatus(true);
|
|
1106
|
-
}
|
|
1107
|
-
return result;
|
|
1108
|
-
}
|
|
1109
1222
|
// ── Multi-server (delegated to plugin) ────────────────────────────────────
|
|
1110
1223
|
getAvailableAuthServers() {
|
|
1111
1224
|
return this.plugin.getAvailableServers?.() ?? [];
|
|
@@ -3219,7 +3332,7 @@ class TenantRegisterComponent {
|
|
|
3219
3332
|
tenantSlugLabel = 'Organization URL';
|
|
3220
3333
|
tenantSlugPlaceholder = 'organization-name';
|
|
3221
3334
|
urlPreviewEnabled = true;
|
|
3222
|
-
urlPreviewPrefix = '
|
|
3335
|
+
urlPreviewPrefix = 'yourapp.com/';
|
|
3223
3336
|
// User Labels
|
|
3224
3337
|
userSectionTitle = 'Your Information';
|
|
3225
3338
|
oauthDescription = 'Recommended: Sign up with your Google account';
|
|
@@ -3232,6 +3345,7 @@ class TenantRegisterComponent {
|
|
|
3232
3345
|
loginLinkAction = 'Sign in';
|
|
3233
3346
|
// Outputs
|
|
3234
3347
|
tenantCreated = new EventEmitter();
|
|
3348
|
+
registerRequested = new EventEmitter();
|
|
3235
3349
|
navigateToLogin = new EventEmitter();
|
|
3236
3350
|
// Form Fields
|
|
3237
3351
|
tenantName = '';
|
|
@@ -3354,64 +3468,49 @@ class TenantRegisterComponent {
|
|
|
3354
3468
|
}
|
|
3355
3469
|
return true;
|
|
3356
3470
|
}
|
|
3357
|
-
|
|
3471
|
+
onOAuthRegister(provider) {
|
|
3358
3472
|
if (!this.isFormValid()) {
|
|
3359
3473
|
this.error = 'Please complete the organization information';
|
|
3360
3474
|
return;
|
|
3361
3475
|
}
|
|
3362
|
-
this.loading = true;
|
|
3363
|
-
this.loadingText = `Signing up with ${provider}...`;
|
|
3364
3476
|
this.error = '';
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
if (result.success && result.user) {
|
|
3371
|
-
this.success = 'Organization created successfully!';
|
|
3372
|
-
this.tenantCreated.emit({ user: result.user });
|
|
3373
|
-
}
|
|
3374
|
-
else {
|
|
3375
|
-
this.error = result.message || 'Registration failed';
|
|
3376
|
-
}
|
|
3377
|
-
}
|
|
3378
|
-
catch (err) {
|
|
3379
|
-
this.error = err.message || 'An unexpected error occurred';
|
|
3380
|
-
}
|
|
3381
|
-
finally {
|
|
3382
|
-
this.loading = false;
|
|
3383
|
-
}
|
|
3477
|
+
this.registerRequested.emit({
|
|
3478
|
+
tenantName: this.tenantName,
|
|
3479
|
+
tenantSlug: this.tenantSlug,
|
|
3480
|
+
provider: provider
|
|
3481
|
+
});
|
|
3384
3482
|
}
|
|
3385
|
-
|
|
3483
|
+
onRegister() {
|
|
3386
3484
|
if (!this.isFormValid()) {
|
|
3387
3485
|
this.error = 'Please fill in all required fields correctly';
|
|
3388
3486
|
return;
|
|
3389
3487
|
}
|
|
3390
|
-
this.loading = true;
|
|
3391
|
-
this.loadingText = 'Creating your organization...';
|
|
3392
3488
|
this.error = '';
|
|
3393
3489
|
this.success = '';
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3490
|
+
this.registerRequested.emit({
|
|
3491
|
+
tenantName: this.tenantName,
|
|
3492
|
+
tenantSlug: this.tenantSlug,
|
|
3493
|
+
displayName: this.displayName,
|
|
3494
|
+
email: this.email,
|
|
3495
|
+
password: this.password,
|
|
3496
|
+
provider: 'emailPassword'
|
|
3497
|
+
});
|
|
3498
|
+
}
|
|
3499
|
+
/** Call from consuming component after handling registerRequested to show loading state */
|
|
3500
|
+
setLoading(loading, text) {
|
|
3501
|
+
this.loading = loading;
|
|
3502
|
+
if (text)
|
|
3503
|
+
this.loadingText = text;
|
|
3504
|
+
}
|
|
3505
|
+
/** Call from consuming component to show success/error after handling registerRequested */
|
|
3506
|
+
setResult(result) {
|
|
3507
|
+
this.loading = false;
|
|
3508
|
+
if (result.success && result.user) {
|
|
3509
|
+
this.success = 'Organization created successfully!';
|
|
3510
|
+
this.tenantCreated.emit({ user: result.user });
|
|
3412
3511
|
}
|
|
3413
|
-
|
|
3414
|
-
this.
|
|
3512
|
+
else if (!result.success) {
|
|
3513
|
+
this.error = result.message || 'Registration failed';
|
|
3415
3514
|
}
|
|
3416
3515
|
}
|
|
3417
3516
|
onLoginClick(event) {
|
|
@@ -3419,7 +3518,7 @@ class TenantRegisterComponent {
|
|
|
3419
3518
|
this.navigateToLogin.emit();
|
|
3420
3519
|
}
|
|
3421
3520
|
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 });
|
|
3422
|
-
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: `
|
|
3521
|
+
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: `
|
|
3423
3522
|
<div class="tenant-register-dialog">
|
|
3424
3523
|
<h2 class="register-title">{{ title }}</h2>
|
|
3425
3524
|
|
|
@@ -3876,6 +3975,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
3876
3975
|
type: Input
|
|
3877
3976
|
}], tenantCreated: [{
|
|
3878
3977
|
type: Output
|
|
3978
|
+
}], registerRequested: [{
|
|
3979
|
+
type: Output
|
|
3879
3980
|
}], navigateToLogin: [{
|
|
3880
3981
|
type: Output
|
|
3881
3982
|
}] } });
|
|
@@ -4057,7 +4158,7 @@ class TenantRegisterDialogComponent {
|
|
|
4057
4158
|
(navigateToLogin)="onNavigateToLogin()">
|
|
4058
4159
|
</lib-tenant-register>
|
|
4059
4160
|
</div>
|
|
4060
|
-
`, 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"] }] });
|
|
4161
|
+
`, 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"] }] });
|
|
4061
4162
|
}
|
|
4062
4163
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TenantRegisterDialogComponent, decorators: [{
|
|
4063
4164
|
type: Component,
|
|
@@ -4107,5 +4208,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
4107
4208
|
* Generated bundle index. Do not edit.
|
|
4108
4209
|
*/
|
|
4109
4210
|
|
|
4110
|
-
export { AUTH_PLUGIN, ApiConnectionService, ApiResponse, AuthPageComponent, AuthService, CsrfService, DbService, FilesService, LoginDialogComponent, MyEnvironmentModel, ProviderRegistryService, RegisterComponent, SigninStatusService, StoneScriptPHPAuth, TenantLoginComponent, TenantLoginDialogComponent, TenantRegisterComponent, TenantRegisterDialogComponent, TokenService, VerifyStatus, provideNgxStoneScriptPhpClient };
|
|
4211
|
+
export { AUTH_PLUGIN, ApiConnectionService, ApiResponse, AuthPageComponent, AuthService, CsrfService, DbService, FilesService, LoginDialogComponent, MyEnvironmentModel, ProgalaxyElabsAuth, ProviderRegistryService, RegisterComponent, SigninStatusService, StoneScriptPHPAuth, TenantLoginComponent, TenantLoginDialogComponent, TenantRegisterComponent, TenantRegisterDialogComponent, TokenService, VerifyStatus, provideNgxStoneScriptPhpClient };
|
|
4111
4212
|
//# sourceMappingURL=progalaxyelabs-ngx-stonescriptphp-client.mjs.map
|