UNPKG

browserify-steam-totp

Version:
162 lines 12.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SteamTotp = exports.SteamAuthenticator = void 0; const buffer_1 = require("buffer"); const axios_1 = __importDefault(require("axios")); const crypto_js_1 = __importDefault(require("crypto-js")); class SteamAuthenticator { constructor() { this._DIGITS = 5; this._PERIOD = 30; this._ALPHABET = '23456789BCDFGHJKMNPQRTVWXY'; } /** * Get the current time in seconds, optionally with a time offset * @param timeOffset Time offset in seconds (optional) * @returns The current time in seconds `number` */ getTime(timeOffset) { return Math.floor(Date.now() / 1000) + (timeOffset || 0); } /** * Generate a one-time authentication code (TOTP) * @param secret The secret key as a string * @param timeOffset Time offset in seconds (optional) * @returns The generated one-time authentication code `string` */ generateAuthCode(secret, timeOffset = 0) { const keyData = this.bufferizeSecret(secret); const time = Math.floor(this.getTime(timeOffset) / this._PERIOD); const buffer = buffer_1.Buffer.allocUnsafe(8); buffer.writeUInt32BE(0, 0); buffer.writeUint32BE(time, 4); const hmac = crypto_js_1.default.HmacSHA1(crypto_js_1.default.lib.WordArray.create(buffer), keyData); const hmacResult = crypto_js_1.default.enc.Hex.parse(hmac.toString()); const hmacBytes = []; for (let i = 0; i < hmacResult.words.length * 4; i++) { hmacBytes.push((hmacResult.words[i >> 2] >> (24 - (i % 4) * 8)) & 0xff); } const start = hmacBytes[hmacBytes.length - 1] & 0x0f; let material = ((hmacBytes[start] & 0x7f) << 24) | ((hmacBytes[start + 1] & 0xff) << 16) | ((hmacBytes[start + 2] & 0xff) << 8) | (hmacBytes[start + 3] & 0xff); let code = ''; for (let i = 0; i < this._DIGITS; i++) { code += this._ALPHABET[material % this._ALPHABET.length]; material = Math.floor(material / this._ALPHABET.length); } return code; } /** * Generate a confirmation key for Steam * @param identitySecret The secret key for Steam authentication * @param time Unix time in seconds * @param tag The tag for the key (e.g., 'conf') * @returns The confirmation key `string` */ generateConfirmationKey(identitySecret, time, tag) { let dataLen = 8; if (tag) { dataLen += tag.length > 32 ? 32 : tag.length; } const buffer = buffer_1.Buffer.allocUnsafe(dataLen); if (typeof buffer.writeBigUInt64BE === 'function') { buffer.writeBigUInt64BE(BigInt(time), 0); } else { buffer.writeUInt32BE(0, 0); buffer.writeUInt32BE(time, 4); } if (tag) { buffer.write(tag, 8); } const hmac = crypto_js_1.default.HmacSHA1(crypto_js_1.default.lib.WordArray.create(buffer), crypto_js_1.default.lib.WordArray.create(buffer_1.Buffer.from(identitySecret, 'base64'))); return crypto_js_1.default.enc.Base64.stringify(hmac); } /** * Generate the device ID based on the SteamID * @param steamid The user's SteamID * @returns The device ID `string` */ getDeviceId(steamid) { const hash = crypto_js_1.default.SHA1(steamid.toString()) .toString(crypto_js_1.default.enc.Hex) .replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12}).*$/, '$1-$2-$3-$4-$5'); return `android:${hash}`; } /** * Asynchronously get the time offset from Steam servers * @returns An object with the time offset and the request time */ async getTimeOffsetAsync() { try { const start = Date.now(); const response = await axios_1.default.post('https://api.steampowered.com/ITwoFactorService/QueryTime/v1/', null, { headers: { 'Content-Length': '0', }, }); const data = response.data.response; if (!data || !data.server_time) { throw new Error('Malformed response'); } const end = Date.now(); const offset = data.server_time - this.getTime(); return { offset, time: end - start, }; } catch (error) { throw new Error(error.message || 'Request failed'); } } /** * Get the time offset from Steam servers using a callback * @param callback The callback function to return the error or result */ getTimeOffset(callback) { const start = Date.now(); axios_1.default .post('https://api.steampowered.com/ITwoFactorService/QueryTime/v1/', null, { headers: { 'Content-Length': '0', }, }) .then((response) => { const data = response.data.response; if (!data || !data.server_time) { return callback(new Error('Malformed response')); } const end = Date.now(); const offset = data.server_time - this.getTime(); callback(null, offset, end - start); }) .catch((error) => { callback(new Error(error.message || 'Request failed')); }); } /** * Convert the secret string into a format that can be used by CryptoJS * @param secret The secret string (in hex or base64) * @returns The parsed secret as a CryptoJS `WordArray` */ bufferizeSecret(secret) { if (typeof secret === 'string') { if (secret.match(/[0-9a-f]{40}/i)) { return crypto_js_1.default.enc.Hex.parse(secret); } else { return crypto_js_1.default.enc.Base64.parse(secret); } } return secret; } } exports.SteamAuthenticator = SteamAuthenticator; exports.SteamTotp = new SteamAuthenticator(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlYW10b3RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9zdGVhbXRvdHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsbUNBQWdDO0FBRWhDLGtEQUEwQjtBQUMxQiwwREFBaUM7QUFFakMsTUFBYSxrQkFBa0I7SUFBL0I7UUFDbUIsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLFlBQU8sR0FBRyxFQUFFLENBQUM7UUFDYixjQUFTLEdBQUcsNEJBQTRCLENBQUM7SUFnTTVELENBQUM7SUE5TEM7Ozs7T0FJRztJQUNILE9BQU8sQ0FBQyxVQUFtQjtRQUN6QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGdCQUFnQixDQUFDLE1BQWMsRUFBRSxVQUFVLEdBQUcsQ0FBQztRQUM3QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTdDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFakUsTUFBTSxNQUFNLEdBQUcsZUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQixNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUU5QixNQUFNLElBQUksR0FBRyxtQkFBUSxDQUFDLFFBQVEsQ0FDNUIsbUJBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFDckMsT0FBTyxDQUNSLENBQUM7UUFDRixNQUFNLFVBQVUsR0FBRyxtQkFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBRTNELE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNyQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3BELFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1NBQ3pFO1FBRUQsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBRXJELElBQUksUUFBUSxHQUNWLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNyQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBRWhDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNkLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3JDLElBQUksSUFBSSxJQUFJLENBQUMs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