mirror of
https://github.com/PretendoNetwork/account.git
synced 2026-04-25 07:22:47 -05:00
Added token checksum to non-access/refresh tokens
This commit is contained in:
parent
a4bc671957
commit
d269258b61
52
package-lock.json
generated
52
package-lock.json
generated
|
|
@ -11,8 +11,10 @@
|
|||
"dependencies": {
|
||||
"aws-sdk": "^2.978.0",
|
||||
"bcrypt": "^5.0.0",
|
||||
"buffer-crc32": "^0.2.13",
|
||||
"colors": "^1.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"crc": "^4.3.2",
|
||||
"dicer": "^0.2.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"email-validator": "^2.0.4",
|
||||
|
|
@ -44,6 +46,7 @@
|
|||
"devDependencies": {
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/buffer-crc32": "^0.2.2",
|
||||
"@types/cors": "^2.8.13",
|
||||
"@types/dicer": "^0.2.2",
|
||||
"@types/express": "^4.17.17",
|
||||
|
|
@ -547,6 +550,15 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/buffer-crc32": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/buffer-crc32/-/buffer-crc32-0.2.2.tgz",
|
||||
"integrity": "sha512-UpJyUKgG33LVehYtv9k2x4HUEY5ThV62YNGFBbQNBgtoky/0tQCceh8BPI9r3XL5hQ1tGmq34jGWNRBKf2P1UQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cacheable-request": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||
|
|
@ -1209,6 +1221,16 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aws-sdk/node_modules/buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
|
||||
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4",
|
||||
"isarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
|
|
@ -1372,14 +1394,12 @@
|
|||
"node": ">=14.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
|
||||
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4",
|
||||
"isarray": "^1.0.0"
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal": {
|
||||
|
|
@ -1670,6 +1690,22 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/crc": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz",
|
||||
"integrity": "sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"buffer": ">=6.0.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"buffer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@
|
|||
"dependencies": {
|
||||
"aws-sdk": "^2.978.0",
|
||||
"bcrypt": "^5.0.0",
|
||||
"buffer-crc32": "^0.2.13",
|
||||
"colors": "^1.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"crc": "^4.3.2",
|
||||
"dicer": "^0.2.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"email-validator": "^2.0.4",
|
||||
|
|
@ -60,6 +62,7 @@
|
|||
"devDependencies": {
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/buffer-crc32": "^0.2.2",
|
||||
"@types/cors": "^2.8.13",
|
||||
"@types/dicer": "^0.2.2",
|
||||
"@types/express": "^4.17.17",
|
||||
|
|
|
|||
|
|
@ -10,10 +10,14 @@ async function APIMiddleware(request: express.Request, _response: express.Respon
|
|||
return next();
|
||||
}
|
||||
|
||||
const token: string = authHeader.split(' ')[1];
|
||||
const pnid: HydratedPNIDDocument | null = await getPNIDByBearerAuth(token);
|
||||
try {
|
||||
const token: string = authHeader.split(' ')[1];
|
||||
const pnid: HydratedPNIDDocument | null = await getPNIDByBearerAuth(token);
|
||||
|
||||
request.pnid = pnid;
|
||||
request.pnid = pnid;
|
||||
} catch (error) {
|
||||
// TODO - Log error
|
||||
}
|
||||
|
||||
return next();
|
||||
}
|
||||
|
|
|
|||
40
src/util.ts
40
src/util.ts
|
|
@ -5,6 +5,8 @@ import fs from 'fs-extra';
|
|||
import express from 'express';
|
||||
import mongoose from 'mongoose';
|
||||
import { ParsedQs } from 'qs';
|
||||
import crc32 from 'buffer-crc32';
|
||||
import crc from 'crc';
|
||||
import { sendMail } from '@/mailer';
|
||||
import { config, disabledFeatures } from '@/config-manager';
|
||||
import { TokenOptions } from '@/types/common/token-options';
|
||||
|
|
@ -56,6 +58,7 @@ export function generateToken(key: string, options: TokenOptions): Buffer | null
|
|||
dataBuffer.writeBigUInt64LE(options.expire_time, 0x6);
|
||||
|
||||
if (options.token_type !== 0x1 && options.token_type !== 0x2) {
|
||||
// * Access and refresh tokens have smaller bodies due to size constraints
|
||||
if (options.access_level === undefined || options.title_id === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -72,20 +75,51 @@ export function generateToken(key: string, options: TokenOptions): Buffer | null
|
|||
const iv: Buffer = Buffer.alloc(16);
|
||||
const cipher: crypto.Cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key, 'hex'), iv);
|
||||
|
||||
return Buffer.concat([
|
||||
const encrypted = Buffer.concat([
|
||||
cipher.update(dataBuffer),
|
||||
cipher.final()
|
||||
]);
|
||||
|
||||
let final: Buffer = encrypted;
|
||||
|
||||
if (options.token_type !== 0x1 && options.token_type !== 0x2) {
|
||||
// * Access and refresh tokens don't get a checksum due to size constraints
|
||||
const checksum: Buffer = crc32(dataBuffer);
|
||||
|
||||
final = Buffer.concat([
|
||||
checksum,
|
||||
final
|
||||
]);
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
export function decryptToken(token: Buffer): Buffer {
|
||||
let encryptedBody: Buffer;
|
||||
let expectedChecksum: number = 0;
|
||||
|
||||
if (token.length === 16) {
|
||||
// * Token is an access/refresh token, no checksum
|
||||
encryptedBody = token;
|
||||
} else {
|
||||
expectedChecksum = token.readUint32BE();
|
||||
encryptedBody = token.subarray(4);
|
||||
}
|
||||
|
||||
const iv: Buffer = Buffer.alloc(16);
|
||||
const decipher: crypto.Decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(config.aes_key, 'hex'), iv);
|
||||
|
||||
return Buffer.concat([
|
||||
decipher.update(token),
|
||||
const decrypted: Buffer = Buffer.concat([
|
||||
decipher.update(encryptedBody),
|
||||
decipher.final()
|
||||
]);
|
||||
|
||||
if (expectedChecksum && (expectedChecksum !== crc.crc32(decrypted))) {
|
||||
throw new Error('Checksum did not match. Failed decrypt. Are you using the right key?');
|
||||
}
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
export function unpackToken(token: Buffer): Token {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user