Skip to content

Commit 9bede79

Browse files
committed
chore(google-one-tap): Use monadic errors when parsing token
1 parent 61e0112 commit 9bede79

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

dotcom-rendering/src/components/GoogleOneTap.importable.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { CountryCode } from '@guardian/libs';
22
import { log } from '@guardian/libs';
33
import type { TAction, TComponentType } from '@guardian/ophan-tracker-js';
44
import { submitComponentEvent } from '../client/ophan/ophan';
5+
import { error, ok, okOrThrow, Result } from '../lib/result';
56
import { useIsSignedIn } from '../lib/useAuthStatus';
67
import { useConsent } from '../lib/useConsent';
78
import { useCountryCode } from '../lib/useCountryCode';
@@ -59,13 +60,19 @@ const getStage = (hostname: string): StageType => {
5960
* @param token A JWT Token
6061
* @returns extracted email address
6162
*/
62-
export const extractEmailFromToken = (token: string): string | undefined => {
63+
export const extractEmailFromToken = (
64+
token: string,
65+
): Result<'ParsingError', string> => {
6366
const payload = token.split('.')[1];
64-
if (!payload) return;
65-
const decoded = atob(payload);
66-
const parsed = JSON.parse(decoded) as Record<string, unknown>;
67-
if (typeof parsed.email !== 'string') return;
68-
return parsed.email;
67+
if (!payload) return error('ParsingError');
68+
try {
69+
const decoded = Buffer.from(token, 'base64').toString();
70+
const parsed = JSON.parse(decoded) as Record<string, unknown>;
71+
if (typeof parsed.email !== 'string') return error('ParsingError');
72+
return ok(parsed.email);
73+
} catch (e) {
74+
return error('ParsingError');
75+
}
6976
};
7077

7178
export const getRedirectUrl = ({
@@ -189,7 +196,7 @@ export const initializeFedCM = async ({
189196
providers: getProviders(stage),
190197
},
191198
})
192-
.catch((error) => {
199+
.catch((e) => {
193200
/**
194201
* The fedcm API hides issues with the user's federated login state
195202
* behind a generic NetworkError. This error is thrown up to 60
@@ -207,7 +214,7 @@ export const initializeFedCM = async ({
207214
'FedCM prompt failed, potentially due to user declining',
208215
);
209216
} else {
210-
throw error;
217+
throw e;
211218
}
212219
});
213220

@@ -216,16 +223,10 @@ export const initializeFedCM = async ({
216223
credentials,
217224
});
218225

219-
const signInEmail = extractEmailFromToken(credentials.token);
220-
if (signInEmail) {
221-
log('identity', `FedCM ID token for ${signInEmail} received`);
222-
} else {
223-
log(
224-
'identity',
225-
'FedCM token received but email could not be extracted from token',
226-
);
227-
return;
228-
}
226+
const signInEmail = okOrThrow(
227+
extractEmailFromToken(credentials.token),
228+
'Failed to extract email from FedCM token',
229+
);
229230

230231
await submitComponentEvent(
231232
{

0 commit comments

Comments
 (0)