Compare commits
2
Commits
b82b989cc8
...
838749df64
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
838749df64 | ||
|
|
3958bda489 |
@@ -233,6 +233,27 @@ export default function AuthForm({ mode, onModeChange, onForgotPassword, onSucce
|
|||||||
By creating an account you agree to our{' '}
|
By creating an account you agree to our{' '}
|
||||||
<a href="/privacy" target="_blank" rel="noopener noreferrer">Privacy Policy</a>.
|
<a href="/privacy" target="_blank" rel="noopener noreferrer">Privacy Policy</a>.
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
{/* On this tab too, and its absence here was a bug (#345).
|
||||||
|
A passkey belongs only on Log In, because you cannot
|
||||||
|
register an account with one — but creating an account is
|
||||||
|
exactly what a new customer reaches for Google to do, so
|
||||||
|
leaving it off the sign-up tab hid the feature from the
|
||||||
|
people it helps most.
|
||||||
|
|
||||||
|
The two consent boxes above are not carried across. Google
|
||||||
|
takes the customer off this site entirely, and a tick that
|
||||||
|
survived that round trip would be a consent recorded from a
|
||||||
|
form nobody submitted. They are asked again, with the same
|
||||||
|
wording, on the step they land on (#342). */}
|
||||||
|
{googleEnabled && (
|
||||||
|
<>
|
||||||
|
<Divider plain style={{ marginBlock: 16 }}>
|
||||||
|
<Text type="secondary" style={{ fontSize: 12 }}>or</Text>
|
||||||
|
</Divider>
|
||||||
|
<GoogleSignInButton returnTo={returnTo} intent="sign-up" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,6 +37,17 @@ function GoogleMark() {
|
|||||||
type Props = Readonly<{
|
type Props = Readonly<{
|
||||||
/** Where to send the customer back to. Validated again on the server. */
|
/** Where to send the customer back to. Validated again on the server. */
|
||||||
returnTo: string;
|
returnTo: string;
|
||||||
|
/**
|
||||||
|
* Which tab this sits on, which changes only the wording.
|
||||||
|
*
|
||||||
|
* One endpoint serves both: it signs in a known identity, links a verified
|
||||||
|
* address, or creates an account. The customer does not know or care which
|
||||||
|
* of those will happen, so the label matches what they came to the tab to
|
||||||
|
* do rather than what the server ends up doing.
|
||||||
|
*
|
||||||
|
* Both spellings are in Google identity guidelines alongside the mark.
|
||||||
|
*/
|
||||||
|
intent?: 'sign-in' | 'sign-up';
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +62,7 @@ type Props = Readonly<{
|
|||||||
* here. It has to be, since anyone can type the URL, and doing it in one place
|
* here. It has to be, since anyone can type the URL, and doing it in one place
|
||||||
* beats doing it in two languages. See `google/returnTo.ts`.
|
* beats doing it in two languages. See `google/returnTo.ts`.
|
||||||
*/
|
*/
|
||||||
export default function GoogleSignInButton({ returnTo }: Props) {
|
export default function GoogleSignInButton({ returnTo, intent = 'sign-in' }: Props) {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
block
|
block
|
||||||
@@ -62,7 +73,7 @@ export default function GoogleSignInButton({ returnTo }: Props) {
|
|||||||
window.location.assign(`/api/auth/google/start?returnTo=${encodeURIComponent(returnTo)}`);
|
window.location.assign(`/api/auth/google/start?returnTo=${encodeURIComponent(returnTo)}`);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Sign in with Google
|
{intent === 'sign-up' ? 'Sign up with Google' : 'Sign in with Google'}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,23 @@ test.describe('Customer accounts', () => {
|
|||||||
// So the button being ABSENT is the behaviour under test here, and it is the
|
// So the button being ABSENT is the behaviour under test here, and it is the
|
||||||
// one that matters: a control that appears and then fails at Google is worse
|
// one that matters: a control that appears and then fails at Google is worse
|
||||||
// than one that was never offered.
|
// than one that was never offered.
|
||||||
|
// The sign-up tab, which #345 left it off entirely. A passkey belongs only on
|
||||||
|
// Log In, because you cannot register an account with one — but creating an
|
||||||
|
// account is exactly what a new customer reaches for Google to do, so its
|
||||||
|
// absence there hid the feature from the people it helps most.
|
||||||
|
//
|
||||||
|
// Asserted as absent for the same reason as the login one: local and QA have
|
||||||
|
// no credentials, so absence is the behaviour that actually runs here.
|
||||||
|
test('offers no Google button on the sign-up tab either, when unconfigured', async ({
|
||||||
|
authModal
|
||||||
|
}) => {
|
||||||
|
await authModal.gotoRegister();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
authModal.registerDialog.getByRole('button', { name: /with Google/i })
|
||||||
|
).toHaveCount(0);
|
||||||
|
});
|
||||||
|
|
||||||
test('offers no Google button when the environment is not configured for it', async ({
|
test('offers no Google button when the environment is not configured for it', async ({
|
||||||
authModal,
|
authModal,
|
||||||
accountModal,
|
accountModal,
|
||||||
|
|||||||
Reference in New Issue
Block a user