Skip to content

Commit 3877017

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

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

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

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ 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 type { Result } from '../lib/result';
6+
import { error, ok, okOrThrow } from '../lib/result';
57
import { useIsSignedIn } from '../lib/useAuthStatus';
68
import { useConsent } from '../lib/useConsent';
79
import { useCountryCode } from '../lib/useCountryCode';
@@ -59,13 +61,19 @@ const getStage = (hostname: string): StageType => {
5961
* @param token A JWT Token
6062
* @returns extracted email address
6163
*/
62-
export const extractEmailFromToken = (token: string): string | undefined => {
64+
export const extractEmailFromToken = (
65+
token: string,
66+
): Result<'ParsingError', string> => {
6367
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;
68+
if (!payload) return error('ParsingError');
69+
try {
70+
const decoded = Buffer.from(token, 'base64').toString();
71+
const parsed = JSON.parse(decoded) as Record<string, unknown>;
72+
if (typeof parsed.email !== 'string') return error('ParsingError');
73+
return ok(parsed.email);
74+
} catch (e) {
75+
return error('ParsingError');
76+
}
6977
};
7078

7179
export const getRedirectUrl = ({
@@ -189,7 +197,7 @@ export const initializeFedCM = async ({
189197
providers: getProviders(stage),
190198
},
191199
})
192-
.catch((error) => {
200+
.catch((e) => {
193201
/**
194202
* The fedcm API hides issues with the user's federated login state
195203
* behind a generic NetworkError. This error is thrown up to 60
@@ -207,7 +215,7 @@ export const initializeFedCM = async ({
207215
'FedCM prompt failed, potentially due to user declining',
208216
);
209217
} else {
210-
throw error;
218+
throw e;
211219
}
212220
});
213221

@@ -216,16 +224,10 @@ export const initializeFedCM = async ({
216224
credentials,
217225
});
218226

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-
}
227+
const signInEmail = okOrThrow(
228+
extractEmailFromToken(credentials.token),
229+
'Failed to extract email from FedCM token',
230+
);
229231

230232
await submitComponentEvent(
231233
{

0 commit comments

Comments
 (0)