Merge pull request #1801 from umbraco/feature/login-on-main-frame

Feature: Login without popup
This commit is contained in:
Jacob Overgaard
2024-05-13 15:49:36 +02:00
committed by GitHub
5 changed files with 33 additions and 13 deletions

View File

@@ -62,21 +62,36 @@ export class UmbAppElement extends UmbLitElement {
path: 'oauth_complete',
component: () => import('./app-error.element.js'),
setup: (component) => {
if (!this.#authContext) {
throw new Error('[Fatal] Auth context is not available');
}
const searchParams = new URLSearchParams(window.location.search);
const hasCode = searchParams.has('code');
(component as UmbAppErrorElement).hideBackButton = true;
(component as UmbAppErrorElement).errorHeadline = this.localize.term('general_login');
(component as UmbAppErrorElement).errorMessage = hasCode
? this.localize.term('errors_externalLoginSuccess')
: this.localize.term('errors_externalLoginFailed');
// Complete the authorization request
this.#authContext?.completeAuthorizationRequest().finally(() => {
// If we don't have an opener, redirect to the root
if (!window.opener) {
history.replaceState(null, '', '');
}
});
// If there is an opener, we are in a popup window, and we should show a different message
// than if we are in the main window. If we are in the main window, we should redirect to the root.
// The authorization request will be completed in the active window (main or popup) and the authorization signal will be sent.
// If we are in a popup window, the storage event in UmbAuthContext will catch the signal and close the window.
// If we are in the main window, the signal will be caught right here and the user will be redirected to the root.
if (window.opener) {
(component as UmbAppErrorElement).errorMessage = hasCode
? this.localize.term('errors_externalLoginSuccess')
: this.localize.term('errors_externalLoginFailed');
} else {
(component as UmbAppErrorElement).errorMessage = hasCode
? this.localize.term('errors_externalLoginRedirectSuccess')
: this.localize.term('errors_externalLoginFailed');
this.observe(this.#authContext.authorizationSignal, () => {
window.location.href = '/';
});
}
// Complete the authorization request, which will send the authorization signal
this.#authContext.completeAuthorizationRequest();
},
},
{

View File

@@ -711,6 +711,7 @@ export default {
externalLoginFailed:
'Serveren mislykkedes i at logge ind med den eksterne loginudbyder. Luk dette vindue og prøv igen.',
externalLoginSuccess: 'Du er nu logget ind. Du kan nu lukke dette vindue.',
externalLoginRedirectSuccess: 'Du er nu logget ind. Du vil blive omdirigeret om et øjeblik.',
},
openidErrors: {
accessDenied: 'Access denied',

View File

@@ -720,6 +720,7 @@ export default {
externalLoginFailed:
'The server failed to authorize you against the external login provider. Please close the window and try again.',
externalLoginSuccess: 'You have successfully logged in. You may now close this window.',
externalLoginRedirectSuccess: 'You have successfully logged in. You will be redirected shortly.',
},
openidErrors: {
accessDenied: 'Access denied',

View File

@@ -731,6 +731,7 @@ export default {
externalLoginFailed:
'The server failed to authorize you against the external login provider. Please close the window and try again.',
externalLoginSuccess: 'You have successfully logged in. You may now close this window.',
externalLoginRedirectSuccess: 'You have successfully logged in. You will be redirected shortly.',
},
openidErrors: {
accessDenied: 'Access denied',

View File

@@ -95,14 +95,16 @@ export class UmbAppAuthModalElement extends UmbModalBaseElement<UmbModalAppAuthC
const providerName =
typeof providerOrManifest === 'string' ? providerOrManifest : providerOrManifest.forProviderName;
await authContext.makeAuthorizationRequest(providerName, false, loginHint, manifest);
// If the user is timed out, we do not want to lose the state, so avoid redirecting to the provider
// and instead just make the authorization request. In all other cases, we want to redirect to the provider.
const isTimedOut = this.data?.userLoginState === 'timedOut';
await authContext.makeAuthorizationRequest(providerName, isTimedOut ? false : true, loginHint, manifest);
const isAuthed = authContext.getIsAuthorized();
this.value = { success: isAuthed };
if (isAuthed) {
this._submitModal();
} else {
this._error = 'Failed to authenticate';
}
} catch (error) {
console.error('[AuthModal] Error submitting auth request', error);