react-native-nitro-totp
Version:
React Native module for TOTP (Time-based One-Time Password) and HOTP (HMAC-based One-Time Password) authentication.
83 lines (74 loc) • 2.63 kB
JavaScript
;
import { NitroModules } from 'react-native-nitro-modules';
import { NitroTotpConstants, SecretSizeBytes } from "./constants.js";
import { SecretSize } from "./types.js";
/**
* NitroSecret class that provides methods for generating cryptographically secure secrets.
*/
export class NitroSecret {
constructor() {
this.nitroSecret = NitroModules.createHybridObject('NitroSecret');
}
/**
* Generates a cryptographically secure random secret key.
* @param options - Optional parameters for secret generation.
* @returns The generated secret as a Base32-encoded string.
*/
generate(options = {}) {
const size = options.size ?? NitroTotpConstants.DEFAULT_SECRET_SIZE;
const sizeInBytes = this.convertToBytes(size);
return this.nitroSecret.generate({
size: sizeInBytes
});
}
/**
* Validates if the given secret key has a valid format.
* @param secretKey - The secret key to check.
* @param options - Optional parameters for secret validation.
* @returns True if the secret key format is valid, false otherwise.
*/
isValid(secretKey, options = {}) {
if (!options.size) {
options.size = SecretSize.STANDARD;
}
const cleanedKey = secretKey.replace(/[-=\s]/g, '').toUpperCase();
const expectedLength = this.getExpectedLength(options.size);
return cleanedKey.length === expectedLength;
}
/**
* Determines expected Base32 character length for validation.
* Returns one of the standard lengths if no specific size is provided.
*/
getExpectedLength(size) {
const sizeInBytes = this.convertToBytes(size);
return Math.ceil(sizeInBytes * 8 / 5);
}
/**
* Converts SecretSize enum or raw bytes to validated byte count.
* Centralizes all size conversion and validation logic.
*/
convertToBytes(size) {
if (typeof size !== 'number') {
throw new Error('Invalid secret size type');
}
// Handle enum values first
if (size in SecretSize) {
return SecretSizeBytes[size];
}
// Handle raw byte values with validation
this.validateByteSize(size);
return size;
}
/**
* Validates byte size against allowed standard sizes.
* Throws descriptive error for invalid sizes to guide developers.
*/
validateByteSize(size) {
const validBytes = Object.values(SecretSizeBytes);
if (!validBytes.includes(size)) {
const sizeInfo = Object.entries(SecretSizeBytes).map(([key, bytes]) => `${SecretSize[key]}=${bytes}bytes`).join(', ');
throw new Error(`Secret size must be one of: ${sizeInfo}`);
}
}
}
//# sourceMappingURL=NitroSecret.js.map