show waiting state while redirecting to the OAuth 2.0 authorization page
This commit is contained in:
@@ -29,7 +29,8 @@ export function useLoginPageBase(platform: 'mobile' | 'desktop') {
|
|||||||
const twoFAVerifyType = ref<string>('passcode');
|
const twoFAVerifyType = ref<string>('passcode');
|
||||||
const oauth2ClientSessionId = ref<string>('');
|
const oauth2ClientSessionId = ref<string>('');
|
||||||
|
|
||||||
const logining = ref<boolean>(false);
|
const loggingInByPassword = ref<boolean>(false);
|
||||||
|
const loggingInByOAuth2 = ref<boolean>(false);
|
||||||
const verifying = ref<boolean>(false);
|
const verifying = ref<boolean>(false);
|
||||||
|
|
||||||
const inputIsEmpty = computed<boolean>(() => !username.value || !password.value);
|
const inputIsEmpty = computed<boolean>(() => !username.value || !password.value);
|
||||||
@@ -73,7 +74,8 @@ export function useLoginPageBase(platform: 'mobile' | 'desktop') {
|
|||||||
tempToken,
|
tempToken,
|
||||||
twoFAVerifyType,
|
twoFAVerifyType,
|
||||||
oauth2ClientSessionId,
|
oauth2ClientSessionId,
|
||||||
logining,
|
loggingInByPassword,
|
||||||
|
loggingInByOAuth2,
|
||||||
verifying,
|
verifying,
|
||||||
// computed states
|
// computed states
|
||||||
inputIsEmpty,
|
inputIsEmpty,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
:autofocus="true"
|
:autofocus="true"
|
||||||
:disabled="show2faInput || logining || verifying"
|
:disabled="show2faInput || loggingInByPassword || loggingInByOAuth2 || verifying"
|
||||||
:label="tt('Username')"
|
:label="tt('Username')"
|
||||||
:placeholder="tt('Your username or email')"
|
:placeholder="tt('Your username or email')"
|
||||||
v-model="username"
|
v-model="username"
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
autocomplete="current-password"
|
autocomplete="current-password"
|
||||||
ref="passwordInput"
|
ref="passwordInput"
|
||||||
type="password"
|
type="password"
|
||||||
:disabled="show2faInput || logining || verifying"
|
:disabled="show2faInput || loggingInByPassword || loggingInByOAuth2 || verifying"
|
||||||
:label="tt('Password')"
|
:label="tt('Password')"
|
||||||
:placeholder="tt('Your password')"
|
:placeholder="tt('Your password')"
|
||||||
v-model="password"
|
v-model="password"
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
type="number"
|
type="number"
|
||||||
autocomplete="one-time-code"
|
autocomplete="one-time-code"
|
||||||
ref="passcodeInput"
|
ref="passcodeInput"
|
||||||
:disabled="logining || verifying"
|
:disabled="loggingInByPassword || loggingInByOAuth2 || verifying"
|
||||||
:label="tt('Passcode')"
|
:label="tt('Passcode')"
|
||||||
:placeholder="tt('Passcode')"
|
:placeholder="tt('Passcode')"
|
||||||
:append-inner-icon="mdiHelpCircleOutline"
|
:append-inner-icon="mdiHelpCircleOutline"
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
/>
|
/>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
type="text"
|
type="text"
|
||||||
:disabled="logining || verifying"
|
:disabled="loggingInByPassword || loggingInByOAuth2 || verifying"
|
||||||
:label="tt('Backup Code')"
|
:label="tt('Backup Code')"
|
||||||
:placeholder="tt('Backup Code')"
|
:placeholder="tt('Backup Code')"
|
||||||
:append-inner-icon="mdiOnepassword"
|
:append-inner-icon="mdiOnepassword"
|
||||||
@@ -100,10 +100,10 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<v-btn block :disabled="inputIsEmpty || logining || verifying"
|
<v-btn block :disabled="inputIsEmpty || loggingInByPassword || loggingInByOAuth2 || verifying"
|
||||||
@click="login" v-if="isInternalAuthEnabled() && !show2faInput">
|
@click="login" v-if="isInternalAuthEnabled() && !show2faInput">
|
||||||
{{ tt('Log In') }}
|
{{ tt('Log In') }}
|
||||||
<v-progress-circular indeterminate size="22" class="ms-2" v-if="logining"></v-progress-circular>
|
<v-progress-circular indeterminate size="22" class="ms-2" v-if="loggingInByPassword"></v-progress-circular>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-col cols="12" class="d-flex align-center px-0" v-if="isInternalAuthEnabled() && isOAuth2Enabled()">
|
<v-col cols="12" class="d-flex align-center px-0" v-if="isInternalAuthEnabled() && isOAuth2Enabled()">
|
||||||
@@ -112,10 +112,12 @@
|
|||||||
<v-divider class="ms-3" />
|
<v-divider class="ms-3" />
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-btn block :disabled="logining || verifying" :href="oauth2LoginUrl" v-if="isOAuth2Enabled()">
|
<v-btn block :disabled="loggingInByPassword || loggingInByOAuth2 || verifying" :href="oauth2LoginUrl"
|
||||||
|
@click="loggingInByOAuth2 = true" v-if="isOAuth2Enabled()">
|
||||||
{{ oauth2LoginDisplayName }}
|
{{ oauth2LoginDisplayName }}
|
||||||
|
<v-progress-circular indeterminate size="22" class="ms-2" v-if="loggingInByOAuth2"></v-progress-circular>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn block :disabled="twoFAInputIsEmpty || logining || verifying"
|
<v-btn block :disabled="twoFAInputIsEmpty || loggingInByPassword || loggingInByOAuth2 || verifying"
|
||||||
@click="verify" v-else-if="show2faInput">
|
@click="verify" v-else-if="show2faInput">
|
||||||
{{ tt('Continue') }}
|
{{ tt('Continue') }}
|
||||||
<v-progress-circular indeterminate size="22" class="ms-2" v-if="verifying"></v-progress-circular>
|
<v-progress-circular indeterminate size="22" class="ms-2" v-if="verifying"></v-progress-circular>
|
||||||
@@ -140,7 +142,7 @@
|
|||||||
<v-card-text class="pt-0">
|
<v-card-text class="pt-0">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" class="text-center">
|
<v-col cols="12" class="text-center">
|
||||||
<language-select-button :disabled="logining || verifying" />
|
<language-select-button :disabled="loggingInByPassword || loggingInByOAuth2 || verifying" />
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12" class="d-flex align-center pt-0">
|
<v-col cols="12" class="d-flex align-center pt-0">
|
||||||
@@ -212,7 +214,8 @@ const {
|
|||||||
tempToken,
|
tempToken,
|
||||||
twoFAVerifyType,
|
twoFAVerifyType,
|
||||||
oauth2ClientSessionId,
|
oauth2ClientSessionId,
|
||||||
logining,
|
loggingInByPassword,
|
||||||
|
loggingInByOAuth2,
|
||||||
verifying,
|
verifying,
|
||||||
inputIsEmpty,
|
inputIsEmpty,
|
||||||
twoFAInputIsEmpty,
|
twoFAInputIsEmpty,
|
||||||
@@ -247,17 +250,17 @@ function login(): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logining.value) {
|
if (loggingInByPassword.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logining.value = true;
|
loggingInByPassword.value = true;
|
||||||
|
|
||||||
rootStore.authorize({
|
rootStore.authorize({
|
||||||
loginName: username.value,
|
loginName: username.value,
|
||||||
password: password.value
|
password: password.value
|
||||||
}).then(authResponse => {
|
}).then(authResponse => {
|
||||||
logining.value = false;
|
loggingInByPassword.value = false;
|
||||||
|
|
||||||
if (authResponse.need2FA) {
|
if (authResponse.need2FA) {
|
||||||
tempToken.value = authResponse.token;
|
tempToken.value = authResponse.token;
|
||||||
@@ -276,7 +279,7 @@ function login(): void {
|
|||||||
doAfterLogin(authResponse);
|
doAfterLogin(authResponse);
|
||||||
router.replace('/');
|
router.replace('/');
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
logining.value = false;
|
loggingInByPassword.value = false;
|
||||||
|
|
||||||
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
||||||
router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`);
|
router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
type="password"
|
type="password"
|
||||||
autocomplete="password"
|
autocomplete="password"
|
||||||
:autofocus="true"
|
:autofocus="true"
|
||||||
:disabled="logining"
|
:disabled="loggingInByOAuth2"
|
||||||
:label="tt('Password')"
|
:label="tt('Password')"
|
||||||
:placeholder="tt('Your password')"
|
:placeholder="tt('Your password')"
|
||||||
v-model="password"
|
v-model="password"
|
||||||
@@ -47,15 +47,15 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<v-btn block type="submit" :disabled="!password || logining" @click="verifyAndLogin">
|
<v-btn block type="submit" :disabled="!password || loggingInByOAuth2" @click="verifyAndLogin">
|
||||||
{{ tt('Continue') }}
|
{{ tt('Continue') }}
|
||||||
<v-progress-circular indeterminate size="22" class="ms-2" v-if="logining"></v-progress-circular>
|
<v-progress-circular indeterminate size="22" class="ms-2" v-if="loggingInByOAuth2"></v-progress-circular>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<router-link class="d-flex align-center justify-center" to="/login"
|
<router-link class="d-flex align-center justify-center" to="/login"
|
||||||
:class="{ 'disabled': logining }">
|
:class="{ 'disabled': loggingInByOAuth2 }">
|
||||||
<v-icon class="icon-with-direction" :icon="mdiChevronLeft"/>
|
<v-icon class="icon-with-direction" :icon="mdiChevronLeft"/>
|
||||||
<span>{{ tt('Back to login page') }}</span>
|
<span>{{ tt('Back to login page') }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
<v-card-text class="pt-0">
|
<v-card-text class="pt-0">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" class="text-center">
|
<v-col cols="12" class="text-center">
|
||||||
<language-select-button :disabled="logining" />
|
<language-select-button :disabled="loggingInByOAuth2" />
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12" class="d-flex align-center pt-0">
|
<v-col cols="12" class="d-flex align-center pt-0">
|
||||||
@@ -146,7 +146,7 @@ const rootStore = useRootStore();
|
|||||||
const {
|
const {
|
||||||
version,
|
version,
|
||||||
password,
|
password,
|
||||||
logining,
|
loggingInByOAuth2,
|
||||||
doAfterLogin
|
doAfterLogin
|
||||||
} = useLoginPageBase('desktop');
|
} = useLoginPageBase('desktop');
|
||||||
|
|
||||||
@@ -197,17 +197,17 @@ function verifyAndLogin(): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logining.value = true;
|
loggingInByOAuth2.value = true;
|
||||||
|
|
||||||
rootStore.authorizeOAuth2({
|
rootStore.authorizeOAuth2({
|
||||||
password: password.value,
|
password: password.value,
|
||||||
token: props.token || ''
|
token: props.token || ''
|
||||||
}).then(authResponse => {
|
}).then(authResponse => {
|
||||||
logining.value = false;
|
loggingInByOAuth2.value = false;
|
||||||
doAfterLogin(authResponse);
|
doAfterLogin(authResponse);
|
||||||
navigateToHome();
|
navigateToHome();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
logining.value = false;
|
loggingInByOAuth2.value = false;
|
||||||
|
|
||||||
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
||||||
router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`);
|
router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`);
|
||||||
@@ -221,16 +221,16 @@ function verifyAndLogin(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!error.value && props.platform && props.token && !props.userName) {
|
if (!error.value && props.platform && props.token && !props.userName) {
|
||||||
logining.value = true;
|
loggingInByOAuth2.value = true;
|
||||||
|
|
||||||
rootStore.authorizeOAuth2({
|
rootStore.authorizeOAuth2({
|
||||||
token: props.token
|
token: props.token
|
||||||
}).then(authResponse => {
|
}).then(authResponse => {
|
||||||
logining.value = false;
|
loggingInByOAuth2.value = false;
|
||||||
doAfterLogin(authResponse);
|
doAfterLogin(authResponse);
|
||||||
navigateToHome();
|
navigateToHome();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
logining.value = false;
|
loggingInByOAuth2.value = false;
|
||||||
|
|
||||||
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
||||||
router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`);
|
router.push(`/verify_email?email=${encodeURIComponent(error.error.context.email)}&emailSent=${error.error.context.hasValidEmailVerifyToken || false}`);
|
||||||
|
|||||||
@@ -47,13 +47,15 @@
|
|||||||
</f7-list>
|
</f7-list>
|
||||||
|
|
||||||
<f7-list class="margin-vertical-half">
|
<f7-list class="margin-vertical-half">
|
||||||
<f7-list-button :class="{ 'disabled': inputIsEmpty || logining }" :text="tt('Log In')" @click="login" v-if="isInternalAuthEnabled()"></f7-list-button>
|
<f7-list-button :class="{ 'disabled': inputIsEmpty || loggingInByPassword || loggingInByOAuth2 }" :text="tt('Log In')"
|
||||||
|
@click="login" v-if="isInternalAuthEnabled()"></f7-list-button>
|
||||||
<f7-list-item class="login-divider display-flex align-items-center" v-if="isInternalAuthEnabled() && isOAuth2Enabled()">
|
<f7-list-item class="login-divider display-flex align-items-center" v-if="isInternalAuthEnabled() && isOAuth2Enabled()">
|
||||||
<hr class="margin-inline-end-half" />
|
<hr class="margin-inline-end-half" />
|
||||||
<small>{{ tt('or') }}</small>
|
<small>{{ tt('or') }}</small>
|
||||||
<hr class="margin-inline-start-half" />
|
<hr class="margin-inline-start-half" />
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
<f7-list-button external :class="{ 'disabled': logining }" :href="oauth2LoginUrl" :text="oauth2LoginDisplayName" v-if="isOAuth2Enabled()"></f7-list-button>
|
<f7-list-button external :class="{ 'disabled': loggingInByPassword || loggingInByOAuth2 }" :href="oauth2LoginUrl" :text="oauth2LoginDisplayName"
|
||||||
|
@click="loggingInByOAuth2 = true" v-if="isOAuth2Enabled()"></f7-list-button>
|
||||||
<f7-block-footer v-if="isInternalAuthEnabled()">
|
<f7-block-footer v-if="isInternalAuthEnabled()">
|
||||||
<span>{{ tt('Don\'t have an account?') }}</span>
|
<span>{{ tt('Don\'t have an account?') }}</span>
|
||||||
<f7-link :class="{'disabled': !isUserRegistrationEnabled()}" href="/signup" :text="tt('Create an account')"></f7-link>
|
<f7-link :class="{'disabled': !isUserRegistrationEnabled()}" href="/signup" :text="tt('Create an account')"></f7-link>
|
||||||
@@ -212,7 +214,8 @@ const {
|
|||||||
tempToken,
|
tempToken,
|
||||||
twoFAVerifyType,
|
twoFAVerifyType,
|
||||||
oauth2ClientSessionId,
|
oauth2ClientSessionId,
|
||||||
logining,
|
loggingInByPassword,
|
||||||
|
loggingInByOAuth2,
|
||||||
verifying,
|
verifying,
|
||||||
inputIsEmpty,
|
inputIsEmpty,
|
||||||
twoFAInputIsEmpty,
|
twoFAInputIsEmpty,
|
||||||
@@ -258,17 +261,17 @@ function login(): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logining.value = true;
|
loggingInByPassword.value = true;
|
||||||
resendVerifyEmail.value = '';
|
resendVerifyEmail.value = '';
|
||||||
hasValidEmailVerifyToken.value = false;
|
hasValidEmailVerifyToken.value = false;
|
||||||
currentPasswordForResendVerifyEmail.value = '';
|
currentPasswordForResendVerifyEmail.value = '';
|
||||||
showLoading(() => logining.value);
|
showLoading(() => loggingInByPassword.value);
|
||||||
|
|
||||||
rootStore.authorize({
|
rootStore.authorize({
|
||||||
loginName: username.value,
|
loginName: username.value,
|
||||||
password: password.value
|
password: password.value
|
||||||
}).then(authResponse => {
|
}).then(authResponse => {
|
||||||
logining.value = false;
|
loggingInByPassword.value = false;
|
||||||
hideLoading();
|
hideLoading();
|
||||||
|
|
||||||
if (authResponse.need2FA) {
|
if (authResponse.need2FA) {
|
||||||
@@ -280,7 +283,7 @@ function login(): void {
|
|||||||
doAfterLogin(authResponse);
|
doAfterLogin(authResponse);
|
||||||
router.refreshPage();
|
router.refreshPage();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
logining.value = false;
|
loggingInByPassword.value = false;
|
||||||
hideLoading();
|
hideLoading();
|
||||||
|
|
||||||
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
if (isUserVerifyEmailEnabled() && error.error && error.error.errorCode === KnownErrorCode.UserEmailNotVerified && error.error.context && error.error.context.email) {
|
||||||
|
|||||||
Reference in New Issue
Block a user