From 05e737cb11b90dc92f4b6dac46fe7bfdb6885c57 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 24 May 2024 12:32:58 +0530 Subject: [PATCH] Add steam as a type --- web/apps/auth/src/services/code.ts | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/web/apps/auth/src/services/code.ts b/web/apps/auth/src/services/code.ts index b02e2314b..74d982849 100644 --- a/web/apps/auth/src/services/code.ts +++ b/web/apps/auth/src/services/code.ts @@ -10,13 +10,19 @@ export interface Code { /** A unique id for the corresponding "auth entity" in our system. */ id?: String; /** The type of the code. */ - type: "totp" | "hotp"; + type: "totp" | "hotp" | "steam"; /** The user's account or email for which this code is used. */ account?: string; /** The name of the entity that issued this code. */ issuer: string; - /** Number of digits in the generated OTP. */ - digits: number; + /** + * Length of the generated OTP. + * + * This is vernacularly called "digits", which is an accurate description + * for the OG TOTP/HOTP codes. However, steam codes are not just digits, so + * we name this as a content-neutral "length". + */ + length: number; /** * The time period (in seconds) for which a single OTP generated from this * code remains valid. @@ -85,7 +91,7 @@ const _codeFromURIString = (id: string, uriString: string): Code => { type, account: parseAccount(path), issuer: parseIssuer(url, path), - digits: parseDigits(url), + length: parseLength(url), period: parsePeriod(url), secret: parseSecret(url), algorithm: parseAlgorithm(url), @@ -130,8 +136,17 @@ const parseIssuer = (url: URL, path: string): string => { return p; }; -const parseDigits = (url: URL): number => - parseInt(url.searchParams.get("digits") ?? "", 10) || 6; +/** + * Parse the length of the generated code. + * + * The URI query param is called digits since originally TOTP/HOTP codes used + * this for generating numeric codes. Now we also support steam, which instead + * shows non-numeric codes, and also with a different default length of 5. + */ +const parseLength = (url: URL, type: Code["type"]): number => { + const defaultLength = type == "steam" ? 5 : 6; + return parseInt(url.searchParams.get("digits") ?? "", 10) || defaultLength; +}; const parsePeriod = (url: URL): number => parseInt(url.searchParams.get("period") ?? "", 10) || 30;