Skip to content

Commit 7db24c4

Browse files
committed
[dashboard] Improve email address already in use
1. Advertise to use another identity provider. 2. Handle same error in New Project wizard. Fixes #5975
1 parent ec744db commit 7db24c4

File tree

6 files changed

+41
-18
lines changed

6 files changed

+41
-18
lines changed

components/dashboard/src/Login.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export function Login() {
9393
} else {
9494
errorMessage = payload.description ? payload.description : `Error: ${payload.error}`;
9595
if (payload.error === "email_taken") {
96-
errorMessage = `Email address already exists. Log in using a different provider.`;
96+
errorMessage = `Email address already used in another account. Please log in with ${(payload as any).host}.`;
9797
}
9898
}
9999
setErrorMessage(errorMessage);

components/dashboard/src/projects/NewProject.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import search from "../icons/search.svg";
1919
import moment from "moment";
2020
import { UserContext } from "../user-context";
2121
import { trackEvent } from "../Analytics";
22+
import exclamation from "../images/exclamation.svg";
2223

2324
export default function NewProject() {
2425
const location = useLocation();
@@ -404,6 +405,7 @@ function GitProviders(props: {
404405
onHostSelected: (host: string, updateUser?: boolean) => void
405406
}) {
406407
const [authProviders, setAuthProviders] = useState<AuthProviderInfo[]>([]);
408+
const [ errorMessage, setErrorMessage ] = useState<string | undefined>(undefined);
407409

408410
useEffect(() => {
409411
(async () => {
@@ -413,6 +415,8 @@ function GitProviders(props: {
413415
}, []);
414416

415417
const selectProvider = async (ap: AuthProviderInfo) => {
418+
setErrorMessage(undefined);
419+
416420
const token = await getGitpodService().server.getToken({ host: ap.host });
417421
if (token) {
418422
props.onHostSelected(ap.host);
@@ -424,8 +428,17 @@ function GitProviders(props: {
424428
onSuccess: async () => {
425429
props.onHostSelected(ap.host, true);
426430
},
427-
onError: (error) => {
428-
console.log(error);
431+
onError: (payload) => {
432+
let errorMessage: string;
433+
if (typeof payload === "string") {
434+
errorMessage = payload;
435+
} else {
436+
errorMessage = payload.description ? payload.description : `Error: ${payload.error}`;
437+
if (payload.error === "email_taken") {
438+
errorMessage = `Email address already used in another account. Please log in with ${(payload as any).host}.`;
439+
}
440+
}
441+
setErrorMessage(errorMessage);
429442
}
430443
});
431444
}
@@ -446,6 +459,18 @@ function GitProviders(props: {
446459
);
447460
})}
448461
</div>
462+
463+
{errorMessage && (
464+
<div className="mt-16 flex space-x-2 py-6 px-6 w-96 justify-between bg-gitpod-kumquat-light rounded-xl">
465+
<div className="pr-3 self-center w-6">
466+
<img src={exclamation} />
467+
</div>
468+
<div className="flex-1 flex flex-col">
469+
<p className="text-gitpod-red text-sm">{errorMessage}</p>
470+
</div>
471+
</div>
472+
)}
473+
449474
</div>
450475
</div>
451476
)

components/dashboard/src/provider-utils.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ async function openAuthorizeWindow(params: OpenAuthorizeWindowParams) {
9393
try {
9494
const payload = JSON.parse(error);
9595
if (typeof payload === "object" && payload.error) {
96-
error = { error: payload.error, description: payload.description };
96+
error = { ...payload };
9797
}
9898
} catch (error) {
9999
console.log(error);

components/server/src/auth/errors.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,11 @@ export namespace SelectAccountException {
6969
}
7070

7171
export interface EmailAddressAlreadyTakenException extends AuthException {
72-
payload: string;
7372
}
7473
export namespace EmailAddressAlreadyTakenException {
7574
const type = "EmailAddressAlreadyTakenException";
76-
export function create(message: string) {
77-
return AuthException.create(type, message, message);
75+
export function create(message: string, payload: object | undefined) {
76+
return AuthException.create(type, message, payload);
7877
}
7978
export function is(error: any): error is EmailAddressAlreadyTakenException {
8079
return AuthException.is(error) && error.authException === type;

components/server/src/auth/generic-auth-provider.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ export class GenericAuthProvider implements AuthProvider {
343343
return this.sendCompletionRedirectWithError(response, err.payload);
344344
}
345345
if (EmailAddressAlreadyTakenException.is(err)) {
346-
return this.sendCompletionRedirectWithError(response, { error: "email_taken" });
346+
return this.sendCompletionRedirectWithError(response, { error: "email_taken", host: err.payload?.host });
347347
}
348348

349349
let message = 'Authorization failed. Please try again.';
@@ -448,15 +448,12 @@ export class GenericAuthProvider implements AuthProvider {
448448
if (!currentGitpodUser) {
449449

450450
// signup new accounts with email adresses already taken is disallowed
451-
const existingUserWithSameEmail = (await this.userDb.findUsersByEmail(primaryEmail))[0];
452-
if (existingUserWithSameEmail) {
453-
try {
454-
await this.userService.asserNoAccountWithEmail(primaryEmail);
455-
} catch (error) {
456-
log.warn(`Login attempt with matching email address.`, { ...defaultLogPayload, authUser, candidate, clientInfo });
457-
done(error, undefined);
458-
return;
459-
}
451+
try {
452+
await this.userService.asserNoAccountWithEmail(primaryEmail);
453+
} catch (error) {
454+
log.warn(`Login attempt with matching email address.`, { ...defaultLogPayload, authUser, candidate, clientInfo });
455+
done(error, undefined);
456+
return;
460457
}
461458
}
462459
}

components/server/src/user/user-service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,10 @@ export class UserService {
335335
/*
336336
* /!\ the given email address is used in another user account.
337337
*/
338+
const authProviderId = existingUser.identities.find(i => i.primaryEmail === email)?.authProviderId;
339+
const host = this.hostContextProvider.getAll().find(c => c.authProvider.authProviderId === authProviderId)?.authProvider?.info?.host || "unknown";
338340

339-
throw EmailAddressAlreadyTakenException.create(`Email address is already in use.`);
341+
throw EmailAddressAlreadyTakenException.create(`Email address is already in use.`, { host });
340342
}
341343

342344
}

0 commit comments

Comments
 (0)