@seaverse/auth-sdk 0.4.2 → 0.4.4
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.
- package/README.md +35 -2
- package/dist/auth-modal.css +1 -1
- package/dist/index.cjs +301 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -6
- package/dist/index.js +280 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -88,16 +88,12 @@ declare class AuthFactory {
|
|
|
88
88
|
static fromEnv(): AuthProvider;
|
|
89
89
|
/**
|
|
90
90
|
* 从配置文件创建认证提供者
|
|
91
|
-
* @deprecated This method requires Node.js fs module and should not be used in browser environments.
|
|
92
|
-
* Use AuthFactory.create() with a config object instead.
|
|
93
91
|
*/
|
|
94
|
-
static fromFile(
|
|
92
|
+
static fromFile(path: string): Promise<AuthProvider>;
|
|
95
93
|
/**
|
|
96
94
|
* 从profile创建认证提供者
|
|
97
|
-
* @deprecated This method requires Node.js fs module and should not be used in browser environments.
|
|
98
|
-
* Use AuthFactory.create() with a config object instead.
|
|
99
95
|
*/
|
|
100
|
-
static fromProfile(
|
|
96
|
+
static fromProfile(profileName?: string): Promise<AuthProvider>;
|
|
101
97
|
}
|
|
102
98
|
|
|
103
99
|
type HookType = 'beforeRequest' | 'afterResponse' | 'onError' | 'onRetry';
|
|
@@ -1470,6 +1466,14 @@ declare class AuthModal {
|
|
|
1470
1466
|
private createLeftPanel;
|
|
1471
1467
|
private createRightPanel;
|
|
1472
1468
|
private createLoginForm;
|
|
1469
|
+
/**
|
|
1470
|
+
* Create new style login view (OAuth-first)
|
|
1471
|
+
*/
|
|
1472
|
+
private createNewStyleLoginView;
|
|
1473
|
+
/**
|
|
1474
|
+
* Create old style login view (Traditional email/password form with original CSS)
|
|
1475
|
+
*/
|
|
1476
|
+
private createOldStyleLoginView;
|
|
1473
1477
|
private createSignupForm;
|
|
1474
1478
|
private createForgotPasswordForm;
|
|
1475
1479
|
private createResetPasswordForm;
|
|
@@ -1497,6 +1501,14 @@ declare class AuthModal {
|
|
|
1497
1501
|
*/
|
|
1498
1502
|
private bindSocialLoginButtons;
|
|
1499
1503
|
private switchView;
|
|
1504
|
+
/**
|
|
1505
|
+
* Show new style login view (OAuth-first)
|
|
1506
|
+
*/
|
|
1507
|
+
private showNewStyleLogin;
|
|
1508
|
+
/**
|
|
1509
|
+
* Show old style login view (traditional email/password form)
|
|
1510
|
+
*/
|
|
1511
|
+
private showOldStyleLogin;
|
|
1500
1512
|
private handleLogin;
|
|
1501
1513
|
private handleSignup;
|
|
1502
1514
|
private handleForgotPassword;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* 生成UUID的跨平台函数
|
|
@@ -745,6 +748,113 @@ class CustomAuthProvider extends AuthProvider {
|
|
|
745
748
|
}
|
|
746
749
|
}
|
|
747
750
|
|
|
751
|
+
/**
|
|
752
|
+
* 配置管理器
|
|
753
|
+
*/
|
|
754
|
+
class ConfigManager {
|
|
755
|
+
constructor(configDir) {
|
|
756
|
+
this.configDir = configDir || path.join(os.homedir(), '.openapi-sdk');
|
|
757
|
+
this.configPath = path.join(this.configDir, 'config.json');
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* 保存认证配置
|
|
761
|
+
*/
|
|
762
|
+
async saveAuth(profileName, authConfig) {
|
|
763
|
+
await this.ensureConfigDir();
|
|
764
|
+
const config = await this.loadConfig();
|
|
765
|
+
config.profiles[profileName] = authConfig;
|
|
766
|
+
await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* 加载认证配置
|
|
770
|
+
*/
|
|
771
|
+
async loadAuth(profileName) {
|
|
772
|
+
const config = await this.loadConfig();
|
|
773
|
+
const authConfig = config.profiles[profileName];
|
|
774
|
+
if (!authConfig) {
|
|
775
|
+
throw new Error(`Profile '${profileName}' not found`);
|
|
776
|
+
}
|
|
777
|
+
return authConfig;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* 列出所有profile
|
|
781
|
+
*/
|
|
782
|
+
async listProfiles() {
|
|
783
|
+
const config = await this.loadConfig();
|
|
784
|
+
return Object.keys(config.profiles);
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* 删除profile
|
|
788
|
+
*/
|
|
789
|
+
async removeProfile(profileName) {
|
|
790
|
+
const config = await this.loadConfig();
|
|
791
|
+
delete config.profiles[profileName];
|
|
792
|
+
await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* 从文件加载配置
|
|
796
|
+
*/
|
|
797
|
+
async loadFromFile(filePath) {
|
|
798
|
+
try {
|
|
799
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
800
|
+
return JSON.parse(content);
|
|
801
|
+
}
|
|
802
|
+
catch (error) {
|
|
803
|
+
throw new Error(`Failed to load config from ${filePath}: ${error}`);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* 保存配置到文件
|
|
808
|
+
*/
|
|
809
|
+
async saveToFile(filePath, authConfig) {
|
|
810
|
+
try {
|
|
811
|
+
await fs.writeFile(filePath, JSON.stringify(authConfig, null, 2), 'utf-8');
|
|
812
|
+
}
|
|
813
|
+
catch (error) {
|
|
814
|
+
throw new Error(`Failed to save config to ${filePath}: ${error}`);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* 加载完整配置文件
|
|
819
|
+
*/
|
|
820
|
+
async loadConfig() {
|
|
821
|
+
try {
|
|
822
|
+
const content = await fs.readFile(this.configPath, 'utf-8');
|
|
823
|
+
return JSON.parse(content);
|
|
824
|
+
}
|
|
825
|
+
catch (error) {
|
|
826
|
+
if (error.code === 'ENOENT') {
|
|
827
|
+
// 文件不存在,返回默认配置
|
|
828
|
+
return { profiles: {} };
|
|
829
|
+
}
|
|
830
|
+
throw error;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* 确保配置目录存在
|
|
835
|
+
*/
|
|
836
|
+
async ensureConfigDir() {
|
|
837
|
+
try {
|
|
838
|
+
await fs.mkdir(this.configDir, { recursive: true });
|
|
839
|
+
}
|
|
840
|
+
catch (error) {
|
|
841
|
+
// 忽略错误,可能目录已存在
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* 获取配置目录路径
|
|
846
|
+
*/
|
|
847
|
+
getConfigDir() {
|
|
848
|
+
return this.configDir;
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* 获取配置文件路径
|
|
852
|
+
*/
|
|
853
|
+
getConfigPath() {
|
|
854
|
+
return this.configPath;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
748
858
|
/**
|
|
749
859
|
* 跨平台环境配置工具
|
|
750
860
|
* 支持 Node.js 和浏览器环境
|
|
@@ -877,19 +987,19 @@ class AuthFactory {
|
|
|
877
987
|
}
|
|
878
988
|
/**
|
|
879
989
|
* 从配置文件创建认证提供者
|
|
880
|
-
* @deprecated This method requires Node.js fs module and should not be used in browser environments.
|
|
881
|
-
* Use AuthFactory.create() with a config object instead.
|
|
882
990
|
*/
|
|
883
|
-
static async fromFile(
|
|
884
|
-
|
|
991
|
+
static async fromFile(path) {
|
|
992
|
+
const configManager = new ConfigManager();
|
|
993
|
+
const config = await configManager.loadFromFile(path);
|
|
994
|
+
return this.create(config);
|
|
885
995
|
}
|
|
886
996
|
/**
|
|
887
997
|
* 从profile创建认证提供者
|
|
888
|
-
* @deprecated This method requires Node.js fs module and should not be used in browser environments.
|
|
889
|
-
* Use AuthFactory.create() with a config object instead.
|
|
890
998
|
*/
|
|
891
|
-
static async fromProfile(
|
|
892
|
-
|
|
999
|
+
static async fromProfile(profileName = 'default') {
|
|
1000
|
+
const configManager = new ConfigManager();
|
|
1001
|
+
const config = await configManager.loadAuth(profileName);
|
|
1002
|
+
return this.create(config);
|
|
893
1003
|
}
|
|
894
1004
|
}
|
|
895
1005
|
|
|
@@ -921,8 +1031,8 @@ const ENVIRONMENT_CONFIGS = {
|
|
|
921
1031
|
},
|
|
922
1032
|
development: {
|
|
923
1033
|
name: 'development',
|
|
924
|
-
baseURL: 'https://
|
|
925
|
-
wsURL: 'wss://
|
|
1034
|
+
baseURL: 'https://account-hub.sg.seaverse.dev',
|
|
1035
|
+
wsURL: 'wss://account-hub.sg.seaverse.dev',
|
|
926
1036
|
isProduction: false,
|
|
927
1037
|
},
|
|
928
1038
|
local: {
|
|
@@ -2804,6 +2914,97 @@ class AuthModal {
|
|
|
2804
2914
|
const container = document.createElement('div');
|
|
2805
2915
|
container.id = 'loginForm';
|
|
2806
2916
|
container.className = 'auth-form-view';
|
|
2917
|
+
// NEW STYLE VIEW (OAuth-first, shown by default)
|
|
2918
|
+
const newStyleView = this.createNewStyleLoginView();
|
|
2919
|
+
container.appendChild(newStyleView);
|
|
2920
|
+
// OLD STYLE VIEW (Traditional email/password, hidden by default)
|
|
2921
|
+
const oldStyleView = this.createOldStyleLoginView();
|
|
2922
|
+
container.appendChild(oldStyleView);
|
|
2923
|
+
return container;
|
|
2924
|
+
}
|
|
2925
|
+
/**
|
|
2926
|
+
* Create new style login view (OAuth-first)
|
|
2927
|
+
*/
|
|
2928
|
+
createNewStyleLoginView() {
|
|
2929
|
+
const view = document.createElement('div');
|
|
2930
|
+
view.id = 'newStyleLoginView';
|
|
2931
|
+
view.className = 'new-style-login-view';
|
|
2932
|
+
// Header
|
|
2933
|
+
const header = document.createElement('div');
|
|
2934
|
+
header.className = 'auth-form-header';
|
|
2935
|
+
const title = document.createElement('h2');
|
|
2936
|
+
title.className = 'auth-form-title';
|
|
2937
|
+
title.textContent = 'Welcome back';
|
|
2938
|
+
const subtitle = document.createElement('p');
|
|
2939
|
+
subtitle.className = 'auth-form-subtitle';
|
|
2940
|
+
subtitle.textContent = 'Please choose a login method to continue';
|
|
2941
|
+
header.appendChild(title);
|
|
2942
|
+
header.appendChild(subtitle);
|
|
2943
|
+
view.appendChild(header);
|
|
2944
|
+
// Form container
|
|
2945
|
+
const form = document.createElement('div');
|
|
2946
|
+
form.className = 'auth-form';
|
|
2947
|
+
// OAuth buttons - only show if enabled
|
|
2948
|
+
const hasOAuth = this.options.enableOAuth &&
|
|
2949
|
+
(this.options.enableOAuth.google || this.options.enableOAuth.discord || this.options.enableOAuth.github);
|
|
2950
|
+
if (hasOAuth) {
|
|
2951
|
+
// Google button (full width, primary style)
|
|
2952
|
+
if (this.options.enableOAuth?.google) {
|
|
2953
|
+
const googleBtn = this.createSocialButton('google', 'Continue with Google', 'login', true);
|
|
2954
|
+
googleBtn.className = 'btn-auth-primary';
|
|
2955
|
+
form.appendChild(googleBtn);
|
|
2956
|
+
}
|
|
2957
|
+
// Social buttons grid (GitHub + Discord)
|
|
2958
|
+
const socialGrid = document.createElement('div');
|
|
2959
|
+
socialGrid.className = 'social-buttons-grid';
|
|
2960
|
+
if (this.options.enableOAuth?.github) {
|
|
2961
|
+
const githubBtn = this.createSocialButton('github', 'GitHub', 'login');
|
|
2962
|
+
socialGrid.appendChild(githubBtn);
|
|
2963
|
+
}
|
|
2964
|
+
if (this.options.enableOAuth?.discord) {
|
|
2965
|
+
const discordBtn = this.createSocialButton('discord', 'Discord', 'login');
|
|
2966
|
+
socialGrid.appendChild(discordBtn);
|
|
2967
|
+
}
|
|
2968
|
+
if (socialGrid.children.length > 0) {
|
|
2969
|
+
form.appendChild(socialGrid);
|
|
2970
|
+
}
|
|
2971
|
+
// Divider
|
|
2972
|
+
const divider = document.createElement('div');
|
|
2973
|
+
divider.className = 'divider';
|
|
2974
|
+
divider.textContent = 'or continue with';
|
|
2975
|
+
form.appendChild(divider);
|
|
2976
|
+
}
|
|
2977
|
+
// "Sign in with Email" button
|
|
2978
|
+
const emailBtn = document.createElement('button');
|
|
2979
|
+
emailBtn.type = 'button';
|
|
2980
|
+
emailBtn.id = 'showOldStyleLogin';
|
|
2981
|
+
emailBtn.className = 'btn-email-toggle';
|
|
2982
|
+
emailBtn.innerHTML = `
|
|
2983
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
2984
|
+
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
|
|
2985
|
+
</svg>
|
|
2986
|
+
<span>Sign in with Email</span>
|
|
2987
|
+
`;
|
|
2988
|
+
form.appendChild(emailBtn);
|
|
2989
|
+
// Terms text
|
|
2990
|
+
const termsText = document.createElement('p');
|
|
2991
|
+
termsText.className = 'terms-text';
|
|
2992
|
+
termsText.innerHTML = `
|
|
2993
|
+
By clicking continue, you agree to our
|
|
2994
|
+
<a href="#" class="terms-link">Terms of Service</a> and
|
|
2995
|
+
<a href="#" class="terms-link">Privacy Policy</a>.
|
|
2996
|
+
`;
|
|
2997
|
+
form.appendChild(termsText);
|
|
2998
|
+
view.appendChild(form);
|
|
2999
|
+
return view;
|
|
3000
|
+
}
|
|
3001
|
+
/**
|
|
3002
|
+
* Create old style login view (Traditional email/password form with original CSS)
|
|
3003
|
+
*/
|
|
3004
|
+
createOldStyleLoginView() {
|
|
3005
|
+
const view = document.createElement('div');
|
|
3006
|
+
view.id = 'oldStyleLoginView';
|
|
3007
|
+
view.className = 'old-style-login-view hidden';
|
|
2807
3008
|
// Header
|
|
2808
3009
|
const header = document.createElement('div');
|
|
2809
3010
|
header.className = 'auth-form-header';
|
|
@@ -2821,7 +3022,7 @@ class AuthModal {
|
|
|
2821
3022
|
subtitle.appendChild(signupLink);
|
|
2822
3023
|
header.appendChild(title);
|
|
2823
3024
|
header.appendChild(subtitle);
|
|
2824
|
-
|
|
3025
|
+
view.appendChild(header);
|
|
2825
3026
|
// Form
|
|
2826
3027
|
const form = document.createElement('form');
|
|
2827
3028
|
form.id = 'loginFormElement';
|
|
@@ -2875,28 +3076,25 @@ class AuthModal {
|
|
|
2875
3076
|
// Social buttons grid (Google + GitHub)
|
|
2876
3077
|
const socialGrid = document.createElement('div');
|
|
2877
3078
|
socialGrid.className = 'social-buttons-grid';
|
|
2878
|
-
// Google button - only if enabled
|
|
2879
3079
|
if (this.options.enableOAuth?.google) {
|
|
2880
3080
|
const googleBtn = this.createSocialButton('google', 'Google', 'login');
|
|
2881
3081
|
socialGrid.appendChild(googleBtn);
|
|
2882
3082
|
}
|
|
2883
|
-
// GitHub button - only if configured
|
|
2884
3083
|
if (this.options.enableOAuth?.github) {
|
|
2885
3084
|
const githubBtn = this.createSocialButton('github', 'Github', 'login');
|
|
2886
3085
|
socialGrid.appendChild(githubBtn);
|
|
2887
3086
|
}
|
|
2888
|
-
// Only add grid if it has buttons
|
|
2889
3087
|
if (socialGrid.children.length > 0) {
|
|
2890
3088
|
form.appendChild(socialGrid);
|
|
2891
3089
|
}
|
|
2892
|
-
// Discord button (full width)
|
|
3090
|
+
// Discord button (full width)
|
|
2893
3091
|
if (this.options.enableOAuth?.discord) {
|
|
2894
3092
|
const discordBtn = this.createSocialButton('discord', 'Discord', 'login', true);
|
|
2895
3093
|
form.appendChild(discordBtn);
|
|
2896
3094
|
}
|
|
2897
3095
|
}
|
|
2898
|
-
|
|
2899
|
-
return
|
|
3096
|
+
view.appendChild(form);
|
|
3097
|
+
return view;
|
|
2900
3098
|
}
|
|
2901
3099
|
createSignupForm() {
|
|
2902
3100
|
const container = document.createElement('div');
|
|
@@ -3504,17 +3702,46 @@ class AuthModal {
|
|
|
3504
3702
|
// Backdrop click to close
|
|
3505
3703
|
const backdrop = this.modal.querySelector('.auth-modal-backdrop');
|
|
3506
3704
|
backdrop?.addEventListener('click', () => this.hide());
|
|
3507
|
-
//
|
|
3508
|
-
const
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
this.
|
|
3705
|
+
// Email form toggle
|
|
3706
|
+
const showEmailForm = this.modal.querySelector('#showEmailForm');
|
|
3707
|
+
showEmailForm?.addEventListener('click', () => {
|
|
3708
|
+
const emailForm = this.modal.querySelector('#emailLoginForm');
|
|
3709
|
+
const emailBtn = this.modal.querySelector('#showEmailForm');
|
|
3710
|
+
emailForm?.classList.remove('hidden');
|
|
3711
|
+
emailBtn?.classList.add('hidden');
|
|
3712
|
+
// Update header
|
|
3713
|
+
const title = this.modal.querySelector('#loginForm .auth-form-title');
|
|
3714
|
+
const subtitle = this.modal.querySelector('#loginForm .auth-form-subtitle');
|
|
3715
|
+
if (title)
|
|
3716
|
+
title.textContent = 'Sign in with Email';
|
|
3717
|
+
if (subtitle)
|
|
3718
|
+
subtitle.textContent = 'Enter your details below';
|
|
3512
3719
|
});
|
|
3720
|
+
const backToSocialLogin = this.modal.querySelector('#backToSocialLogin');
|
|
3721
|
+
backToSocialLogin?.addEventListener('click', () => {
|
|
3722
|
+
const emailForm = this.modal.querySelector('#emailLoginForm');
|
|
3723
|
+
const emailBtn = this.modal.querySelector('#showEmailForm');
|
|
3724
|
+
emailForm?.classList.add('hidden');
|
|
3725
|
+
emailBtn?.classList.remove('hidden');
|
|
3726
|
+
// Restore header
|
|
3727
|
+
const title = this.modal.querySelector('#loginForm .auth-form-title');
|
|
3728
|
+
const subtitle = this.modal.querySelector('#loginForm .auth-form-subtitle');
|
|
3729
|
+
if (title)
|
|
3730
|
+
title.textContent = 'Welcome back';
|
|
3731
|
+
if (subtitle)
|
|
3732
|
+
subtitle.textContent = 'Please choose a login method to continue';
|
|
3733
|
+
});
|
|
3734
|
+
// View switching
|
|
3513
3735
|
const showLogin = this.modal.querySelector('#showLogin');
|
|
3514
3736
|
showLogin?.addEventListener('click', (e) => {
|
|
3515
3737
|
e.preventDefault();
|
|
3516
3738
|
this.switchView('login');
|
|
3517
3739
|
});
|
|
3740
|
+
const showSignup = this.modal.querySelector('#showSignup');
|
|
3741
|
+
showSignup?.addEventListener('click', (e) => {
|
|
3742
|
+
e.preventDefault();
|
|
3743
|
+
this.switchView('signup');
|
|
3744
|
+
});
|
|
3518
3745
|
const forgotPasswordLink = this.modal.querySelector('#forgotPasswordLink');
|
|
3519
3746
|
forgotPasswordLink?.addEventListener('click', (e) => {
|
|
3520
3747
|
e.preventDefault();
|
|
@@ -3568,6 +3795,11 @@ class AuthModal {
|
|
|
3568
3795
|
}
|
|
3569
3796
|
});
|
|
3570
3797
|
});
|
|
3798
|
+
// Login view style switching
|
|
3799
|
+
const showOldStyleLogin = this.modal.querySelector('#showOldStyleLogin');
|
|
3800
|
+
showOldStyleLogin?.addEventListener('click', () => {
|
|
3801
|
+
this.showOldStyleLogin();
|
|
3802
|
+
});
|
|
3571
3803
|
// Form submissions
|
|
3572
3804
|
const loginForm = this.modal.querySelector('#loginFormElement');
|
|
3573
3805
|
loginForm?.addEventListener('submit', (e) => this.handleLogin(e));
|
|
@@ -3668,6 +3900,32 @@ class AuthModal {
|
|
|
3668
3900
|
const targetView = this.modal.querySelector(`#${viewMap[view]}`);
|
|
3669
3901
|
targetView?.classList.remove('hidden');
|
|
3670
3902
|
this.currentView = view;
|
|
3903
|
+
// When switching to login view, reset to new style
|
|
3904
|
+
if (view === 'login') {
|
|
3905
|
+
this.showNewStyleLogin();
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
/**
|
|
3909
|
+
* Show new style login view (OAuth-first)
|
|
3910
|
+
*/
|
|
3911
|
+
showNewStyleLogin() {
|
|
3912
|
+
if (!this.modal)
|
|
3913
|
+
return;
|
|
3914
|
+
const newStyleView = this.modal.querySelector('#newStyleLoginView');
|
|
3915
|
+
const oldStyleView = this.modal.querySelector('#oldStyleLoginView');
|
|
3916
|
+
newStyleView?.classList.remove('hidden');
|
|
3917
|
+
oldStyleView?.classList.add('hidden');
|
|
3918
|
+
}
|
|
3919
|
+
/**
|
|
3920
|
+
* Show old style login view (traditional email/password form)
|
|
3921
|
+
*/
|
|
3922
|
+
showOldStyleLogin() {
|
|
3923
|
+
if (!this.modal)
|
|
3924
|
+
return;
|
|
3925
|
+
const newStyleView = this.modal.querySelector('#newStyleLoginView');
|
|
3926
|
+
const oldStyleView = this.modal.querySelector('#oldStyleLoginView');
|
|
3927
|
+
newStyleView?.classList.add('hidden');
|
|
3928
|
+
oldStyleView?.classList.remove('hidden');
|
|
3671
3929
|
}
|
|
3672
3930
|
async handleLogin(e) {
|
|
3673
3931
|
e.preventDefault();
|