Move to separate file
This commit is contained in:
parent
370b28f9e4
commit
36aa33ed5a
4 changed files with 51 additions and 27 deletions
|
@ -7,6 +7,7 @@
|
|||
"@ente/accounts": "*",
|
||||
"@ente/eslint-config": "*",
|
||||
"@ente/shared": "*",
|
||||
"jssha": "~3.3.1",
|
||||
"otpauth": "^9"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}`;
|
||||
}
|
||||
}
|
||||
|
|
46
web/apps/auth/src/services/steam.ts
Normal file
46
web/apps/auth/src/services/steam.ts
Normal 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");
|
||||
};
|
|
@ -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).
|
||||
|
|
Loading…
Reference in a new issue