Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions app/scripts/services/oauth/oauth-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { AuthConnection } from '@metamask/seedless-onboarding-controller';
import log from 'loglevel';
import { OAuthErrorMessages } from '../../../../shared/modules/error';
import {
isUserCancelledLoginError,
OAuthErrorMessages,
} from '../../../../shared/modules/error';
import { checkForLastError } from '../../../../shared/modules/browser-runtime.utils';
import { TraceName, TraceOperation } from '../../../../shared/lib/trace';
import { BaseLoginHandler } from './base-login-handler';
Expand Down Expand Up @@ -204,12 +207,13 @@ export default class OAuthService {
reject(error);
}
} else {
if (this.#isUserCancelledLoginError()) {
reject(
new Error(OAuthErrorMessages.USER_CANCELLED_LOGIN_ERROR),
);
const userCancelledLoginError =
this.#getUserCancelledLoginError();
if (userCancelledLoginError) {
reject(userCancelledLoginError);
return;
}
// Throw default error for no redirect URL found
reject(
new Error(OAuthErrorMessages.NO_REDIRECT_URL_FOUND_ERROR),
);
Expand Down Expand Up @@ -357,9 +361,12 @@ export default class OAuthService {
return url.searchParams.get('code');
}

#isUserCancelledLoginError(): boolean {
#getUserCancelledLoginError(): Error | undefined {
const error = checkForLastError();
return error?.message === OAuthErrorMessages.USER_CANCELLED_LOGIN_ERROR;
if (isUserCancelledLoginError(error)) {
return error;
}
return undefined;
}

async setMarketingConsent(
Expand Down
17 changes: 17 additions & 0 deletions shared/modules/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export enum OAuthErrorMessages {
USER_CANCELLED_LOGIN_ERROR = 'The user did not approve access.',
// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
// eslint-disable-next-line @typescript-eslint/naming-convention
USER_CANCELLED_LOGIN_ERROR_FIREFOX = 'User cancelled or denied access.',
// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
// eslint-disable-next-line @typescript-eslint/naming-convention
NO_REDIRECT_URL_FOUND_ERROR = 'No redirect URL found',
// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand All @@ -47,3 +50,17 @@ export enum OAuthErrorMessages {
// eslint-disable-next-line @typescript-eslint/naming-convention
INVALID_OAUTH_STATE_ERROR = 'Invalid OAuth state',
}

/**
* Checks if the Web Authentication error is a user cancelled error.
*
* @param error - The error to check.
* @returns True if the error is a user cancelled login error, false otherwise.
*/
export function isUserCancelledLoginError(error: Error | undefined): boolean {
// NOTE: Firefox and chrome have different error messages for user cancelled the social login window.
return (
error?.message === OAuthErrorMessages.USER_CANCELLED_LOGIN_ERROR ||
error?.message === OAuthErrorMessages.USER_CANCELLED_LOGIN_ERROR_FIREFOX
);
}
12 changes: 6 additions & 6 deletions ui/pages/onboarding-flow/welcome/welcome.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import React, {
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom-v5-compat';
import log from 'loglevel';
import { Box } from '../../../components/component-library';
import {
ONBOARDING_COMPLETION_ROUTE,
Expand Down Expand Up @@ -41,7 +40,10 @@ import {
import { getIsSeedlessOnboardingFeatureEnabled } from '../../../../shared/modules/environment';
import { getBrowserName } from '../../../../shared/modules/browser-runtime.utils';
import { PLATFORM_FIREFOX } from '../../../../shared/constants/app';
import { OAuthErrorMessages } from '../../../../shared/modules/error';
import {
isUserCancelledLoginError,
OAuthErrorMessages,
} from '../../../../shared/modules/error';
import { TraceName, TraceOperation } from '../../../../shared/lib/trace';
import {
AlignItems,
Expand Down Expand Up @@ -214,7 +216,7 @@ export default function OnboardingWelcome() {
error instanceof Error ? error.message : 'Unknown error';

// Map raw OAuth error messages to UI modal-friendly constants
if (errorMessage === OAuthErrorMessages.USER_CANCELLED_LOGIN_ERROR) {
if (isUserCancelledLoginError(error)) {
setLoginError(null);
return;
}
Expand Down Expand Up @@ -354,9 +356,7 @@ export default function OnboardingWelcome() {
);

const handleLoginError = useCallback((error) => {
log.error('handleLoginError::error', error);
const errorMessage = error.message;
if (errorMessage === OAuthErrorMessages.USER_CANCELLED_LOGIN_ERROR) {
if (isUserCancelledLoginError(error)) {
setLoginError(null);
} else {
setLoginError(LOGIN_ERROR.GENERIC);
Expand Down
Loading