mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
fix(sso): route mobile sign-in through the web callback (#3060)
This commit is contained in:
1 parent
1076728241
commit
12bfaa83ba
7 files changed
+62
-18
No files matched your search
@@ -368,6 +368,7 @@
|
||||
}
|
||||
|
||||
.ssoRetryButton {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 0.625rem;
|
||||
border: none;
|
||||
@@ -376,6 +377,7 @@
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: background 120ms ease;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
|
||||
import * as AuthenticationCommands from '@app/features/auth/commands/AuthenticationCommands';
|
||||
import styles from '@app/features/auth/components/pages/LoginPage.module.css';
|
||||
import {
|
||||
@@ -12,6 +13,7 @@ import {safeRedirectTarget} from '@app/features/auth/utils/SafeRedirect';
|
||||
import {BACK_TO_SIGN_IN_DESCRIPTOR, TRY_AGAIN_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors';
|
||||
import * as RouterUtils from '@app/features/navigation/utils/RouterUtils';
|
||||
import * as FormUtils from '@app/lib/forms';
|
||||
import {SSO_MOBILE_CALLBACK_URI, SSO_MOBILE_STATE_PREFIX} from '@fluxer/constants/src/SsoConstants';
|
||||
import {msg} from '@lingui/core/macro';
|
||||
import {Trans, useLingui} from '@lingui/react/macro';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
@@ -29,6 +31,10 @@ const FAILED_TO_COMPLETE_SSO_SIGN_IN_DESCRIPTOR = msg({
|
||||
message: 'Failed to complete SSO sign-in',
|
||||
comment: 'Short label in the authentication SSO callback page. Keep the tone plain and specific.',
|
||||
});
|
||||
const OPEN_PRODUCT_DESCRIPTOR = msg({
|
||||
message: 'Open {productName}',
|
||||
comment: 'Button that hands SSO sign-in back to the mobile app. productName is the app name.',
|
||||
});
|
||||
const SSO_TIMEOUT_MS = 30_000;
|
||||
const SsoCallbackPage = observer(function SsoCallbackPage() {
|
||||
const {i18n} = useLingui();
|
||||
@@ -37,6 +43,9 @@ const SsoCallbackPage = observer(function SsoCallbackPage() {
|
||||
const state = params['get']('state');
|
||||
const providerError = params['get']('error');
|
||||
const providerErrorDescription = params['get']('error_description');
|
||||
const mobileCallbackUrl = state?.startsWith(SSO_MOBILE_STATE_PREFIX)
|
||||
? `${SSO_MOBILE_CALLBACK_URI}${window.location.search}`
|
||||
: null;
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [isProcessing, setIsProcessing] = useState(true);
|
||||
const abortControllerRef = useRef<AbortController | null>(null);
|
||||
@@ -54,6 +63,10 @@ const SsoCallbackPage = observer(function SsoCallbackPage() {
|
||||
}
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (mobileCallbackUrl) {
|
||||
window.location.replace(mobileCallbackUrl);
|
||||
return;
|
||||
}
|
||||
const controller = new AbortController();
|
||||
abortControllerRef.current = controller;
|
||||
const timeoutId = setTimeout(() => {
|
||||
@@ -97,7 +110,28 @@ const SsoCallbackPage = observer(function SsoCallbackPage() {
|
||||
clearTimeout(timeoutId);
|
||||
controller.abort();
|
||||
};
|
||||
}, [code, state, providerError, providerErrorDescription, i18n]);
|
||||
}, [code, state, providerError, providerErrorDescription, mobileCallbackUrl, i18n]);
|
||||
if (mobileCallbackUrl) {
|
||||
return (
|
||||
<div className={styles.loginContainer} data-flx="auth.sso-callback-page.login-container--mobile">
|
||||
<h1 className={styles.title} data-flx="auth.sso-callback-page.title--mobile">
|
||||
<Trans>Completing sign-in…</Trans>
|
||||
</h1>
|
||||
<p className={styles.ssoProcessingHint} data-flx="auth.sso-callback-page.sso-processing-hint--mobile">
|
||||
<Trans>Jump straight to the app to continue.</Trans>
|
||||
</p>
|
||||
<div className={styles.ssoCallbackActions} data-flx="auth.sso-callback-page.sso-callback-actions--mobile">
|
||||
<a
|
||||
href={mobileCallbackUrl}
|
||||
className={styles.ssoRetryButton}
|
||||
data-flx="auth.sso-callback-page.sso-open-app-button"
|
||||
>
|
||||
{i18n._(OPEN_PRODUCT_DESCRIPTOR, {productName: PRODUCT_NAME})}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (error) {
|
||||
return (
|
||||
<div className={styles.loginContainer} data-flx="auth.sso-callback-page.login-container">
|
||||
|
||||
Reference in new issue
Block a user