Move to separate file

This commit is contained in:
Manav Rathi 2024-05-24 13:08:41 +05:30
parent 370b28f9e4
commit 36aa33ed5a
No known key found for this signature in database
4 changed files with 51 additions and 27 deletions

View file

@ -7,6 +7,7 @@
"@ente/accounts": "*",
"@ente/eslint-config": "*",
"@ente/shared": "*",
"jssha": "~3.3.1",
"otpauth": "^9"
}
}

View file

@ -215,30 +215,3 @@ export const generateOTPs = (code: Code): [otp: string, nextOTP: string] => {
}
return [otp, nextOTP];
};
/**
* Steam OTPs.
*
* Steam's algorithm is a custom variant of TOTP that uses a 26-character
* alphabet instead of digits.
*
* A Dart implementation of the algorithm can be found in
* https://github.com/elliotwutingfeng/steam_totp/blob/main/lib/src/steam_totp_base.dart
* (MIT license), and we use that as a reference. Our implementation is written
* in the style of the other TOTP/HOTP classes that are provided by the otpauth
* JS library that we use for the normal TOTP/HOTP generation
* https://github.com/hectorm/otpauth/blob/master/src/hotp.js (MIT license).
*/
class Steam {
secret: string;
period: number;
constructor({ secret }: { secret: string }) {
this.secret = secret;
this.period = 30;
}
generate({ timestamp }: { timestamp: number } = { timestamp: Date.now() }) {
return `${timestamp}`;
}
}

View file

@ -0,0 +1,46 @@
import jsSHA from "jssha";
/**
* Steam OTPs.
*
* Steam's algorithm is a custom variant of TOTP that uses a 26-character
* alphabet instead of digits.
*
* A Dart implementation of the algorithm can be found in
* https://github.com/elliotwutingfeng/steam_totp/blob/main/lib/src/steam_totp_base.dart
* (MIT license), and we use that as a reference. Our implementation is written
* in the style of the other TOTP/HOTP classes that are provided by the otpauth
* JS library that we use for the normal TOTP/HOTP generation
* https://github.com/hectorm/otpauth/blob/master/src/hotp.js (MIT license).
*/
export class Steam {
secret: string;
period: number;
constructor({ secret }: { secret: string }) {
this.secret = secret;
this.period = 30;
}
async generate(
{ timestamp }: { timestamp: number } = { timestamp: Date.now() },
) {
const counter = Math.floor(timestamp / 1000 / this.period);
// const digest = new Uint8Array(
// sha1HMACDigest(this.secret, uintToBuf(counter)),
// );
return `${timestamp}`;
}
}
// We don't necessarily need this dependency, we could use SubtleCrypto here
// instead too. However, SubtleCrypto has an async interface, and we already
// have a transitive dependency on jssha via otpauth, so just using it here
// doesn't increase our bundle size any further.
const sha1HMACDiggest = (key: ArrayBuffer, message: ArrayBuffer) => {
const hmac = new jsSHA("SHA-1", "ARRAYBUFFER");
hmac.setHMACKey(key, "ARRAYBUFFER");
hmac.update(message);
return hmac.getHMAC("ARRAYBUFFER");
};

View file

@ -198,3 +198,7 @@ some cases.
- [otpauth](https://github.com/hectorm/otpauth) is used for the generation of
the actual OTP from the user's TOTP/HOTP secret.
- However, otpauth doesn't support steam OTPs. For these, we need to compute
the SHA-1, and we use the same library, `jssha` that `otpauth` uses (since
it is already part of our bundle).