feat: Show details of invalid invite (#1970)
Resolves https://github.com/webrecorder/browsertrix/issues/1912 ### Changes - Show support email, if available, in invalid invite error message - Separate error message for invite email that doesn't match current user's
This commit is contained in:
parent
d38abbca7f
commit
dd6c33a59d
@ -188,6 +188,7 @@ export class App extends LiteElement {
|
|||||||
maxScale: 0,
|
maxScale: 0,
|
||||||
billingEnabled: false,
|
billingEnabled: false,
|
||||||
salesEmail: "",
|
salesEmail: "",
|
||||||
|
supportEmail: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { localized, msg, str } from "@lit/localize";
|
import { localized, msg, str } from "@lit/localize";
|
||||||
import { Task } from "@lit/task";
|
import { Task } from "@lit/task";
|
||||||
import { html } from "lit";
|
import { html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import { renderInviteMessage } from "./ui/inviteMessage";
|
import { renderInviteMessage } from "./ui/inviteMessage";
|
||||||
@ -15,7 +15,7 @@ import { ROUTES } from "@/routes";
|
|||||||
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
|
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
|
||||||
import { isApiError } from "@/utils/api";
|
import { isApiError } from "@/utils/api";
|
||||||
import type { Auth, AuthState } from "@/utils/AuthService";
|
import type { Auth, AuthState } from "@/utils/AuthService";
|
||||||
import { AppStateService } from "@/utils/state";
|
import appState, { AppStateService, use } from "@/utils/state";
|
||||||
import { formatAPIUser } from "@/utils/user";
|
import { formatAPIUser } from "@/utils/user";
|
||||||
|
|
||||||
import "./ui/org-form";
|
import "./ui/org-form";
|
||||||
@ -32,6 +32,9 @@ export class AcceptInvite extends TailwindElement {
|
|||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
email?: string;
|
email?: string;
|
||||||
|
|
||||||
|
@use()
|
||||||
|
appState = appState;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
private serverError?: string;
|
private serverError?: string;
|
||||||
|
|
||||||
@ -49,9 +52,7 @@ export class AcceptInvite extends TailwindElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
get _isLoggedIn(): boolean {
|
get _isLoggedIn(): boolean {
|
||||||
return Boolean(
|
return Boolean(this.authState && this.email);
|
||||||
this.authState && this.email && this.authState.username === this.email,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly _api = new APIController(this);
|
readonly _api = new APIController(this);
|
||||||
@ -69,7 +70,7 @@ export class AcceptInvite extends TailwindElement {
|
|||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
if (!this._isLoggedIn) {
|
if (!this._isLoggedIn) {
|
||||||
this._notify.toast({
|
this._notify.toast({
|
||||||
message: msg("Log in to continue."),
|
message: msg("Please log in to accept this invite."),
|
||||||
variant: "warning",
|
variant: "warning",
|
||||||
icon: "exclamation-triangle",
|
icon: "exclamation-triangle",
|
||||||
});
|
});
|
||||||
@ -152,6 +153,9 @@ export class AcceptInvite extends TailwindElement {
|
|||||||
error: (err) =>
|
error: (err) =>
|
||||||
html`<btrix-alert variant="danger">
|
html`<btrix-alert variant="danger">
|
||||||
<div>${err instanceof Error ? err.message : err}</div>
|
<div>${err instanceof Error ? err.message : err}</div>
|
||||||
|
${this.authState && this.authState.username !== this.email
|
||||||
|
? nothing
|
||||||
|
: html`
|
||||||
<a
|
<a
|
||||||
href=${ROUTES.home}
|
href=${ROUTES.home}
|
||||||
@click=${this._navigate.link}
|
@click=${this._navigate.link}
|
||||||
@ -159,6 +163,7 @@ export class AcceptInvite extends TailwindElement {
|
|||||||
>
|
>
|
||||||
${msg("Go to home page")}
|
${msg("Go to home page")}
|
||||||
</a>
|
</a>
|
||||||
|
`}
|
||||||
</btrix-alert> `,
|
</btrix-alert> `,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
@ -181,7 +186,38 @@ export class AcceptInvite extends TailwindElement {
|
|||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.debug(e);
|
console.debug(e);
|
||||||
throw new Error(msg("This invitation is not valid."));
|
|
||||||
|
const status = isApiError(e) ? e.statusCode : null;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case 404:
|
||||||
|
throw new Error(
|
||||||
|
msg(
|
||||||
|
"This invite doesn't exist or has expired. Please ask the organization administrator to resend an invitation.",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case 400: {
|
||||||
|
if (auth.username === this.email) {
|
||||||
|
throw new Error(
|
||||||
|
msg(
|
||||||
|
str`This is not a valid invite, or it may have expired. If you believe this is an error, please contact ${this.appState.settings?.supportEmail || msg("your Browsertrix administrator")} for help.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
msg(
|
||||||
|
str`This invitation is for ${this.email}. You are currently logged in as ${auth.username}. Please log in with the correct email to access this invite.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error(
|
||||||
|
msg(
|
||||||
|
str`Something unexpected went wrong retrieving this invite. Please contact ${this.appState.settings?.supportEmail || msg("your Browsertrix administrator")} for help.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { localized, msg } from "@lit/localize";
|
import { localized, msg, str } from "@lit/localize";
|
||||||
import { Task } from "@lit/task";
|
import { Task } from "@lit/task";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
@ -132,16 +132,27 @@ export class Join extends LiteElement {
|
|||||||
`/api/users/invite/${token}?email=${encodeURIComponent(email)}`,
|
`/api/users/invite/${token}?email=${encodeURIComponent(email)}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (resp.status === 200) {
|
switch (resp.status) {
|
||||||
|
case 200:
|
||||||
return (await resp.json()) as UserOrgInviteInfo;
|
return (await resp.json()) as UserOrgInviteInfo;
|
||||||
} else if (resp.status === 404) {
|
case 404:
|
||||||
throw new Error(
|
throw new Error(
|
||||||
msg(
|
msg(
|
||||||
"This invite doesn't exist or has expired. Please ask the organization administrator to resend an invitation.",
|
"This invite doesn't exist or has expired. Please ask the organization administrator to resend an invitation.",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
case 400:
|
||||||
throw new Error(msg("This invitation is not valid."));
|
throw new Error(
|
||||||
|
msg(
|
||||||
|
str`This is not a valid invite, or it may have expired. If you believe this is an error, please contact ${this.appState.settings?.supportEmail || msg("your Browsertrix administrator")} for help.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new Error(
|
||||||
|
msg(
|
||||||
|
str`Something unexpected went wrong retrieving this invite. Please contact ${this.appState.settings?.supportEmail || msg("your Browsertrix administrator")} for help.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,4 +7,5 @@ export type AppSettings = {
|
|||||||
maxScale: number;
|
maxScale: number;
|
||||||
billingEnabled: boolean;
|
billingEnabled: boolean;
|
||||||
salesEmail: string;
|
salesEmail: string;
|
||||||
|
supportEmail: string;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user