jwt-transform
Version:
transform your real jwt token into fake jwt token.
141 lines (140 loc) • 6.19 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JwtTransform = void 0;
var EJwtTransform;
(function (EJwtTransform) {
EJwtTransform["ENC"] = "encrypt";
EJwtTransform["DEC"] = "decrypt";
})(EJwtTransform || (EJwtTransform = {}));
class JwtTransform {
static alphabet = 'abcdefghijklmnopqrstuvwxyz';
static alphacount = JwtTransform.alphabet.length;
static lca = JwtTransform.alphabet.toLowerCase();
static uca = JwtTransform.alphabet.toUpperCase();
static secretKeyCache = {};
static validate(secretKey, token, rotate, rotateType) {
let tokenType = 'plainText';
if (rotateType !== EJwtTransform.DEC) {
tokenType = 'cipherText';
}
if (token.length <= 0) {
throw new TypeError(`${tokenType} not to be a empty`);
}
else if (typeof token !== 'string') {
throw new TypeError(`${tokenType} must be a string format`);
}
else if (token.split('.').length !== 3) {
throw new TypeError(`${tokenType} must be a jwt format`);
}
else if (rotate <= 0) {
throw new TypeError('rotate not to be a empty');
}
else if (typeof rotate !== 'number') {
throw new TypeError('rotate must be a number format');
}
else if (secretKey.length <= 20) {
throw new TypeError('secretKey length must be a greater than 20 characters');
}
}
static validSecretKey(secretKey, token, rotate, rotateType) {
JwtTransform.validate(secretKey, token, rotate, rotateType);
let newToken = token;
if (rotateType === EJwtTransform.ENC || rotateType === EJwtTransform.DEC) {
newToken = token;
}
const validSecretKey = /[^A-Z0-9]/i.test(secretKey);
if (validSecretKey) {
throw new TypeError('secretKey invalid format');
}
else if (newToken.includes(secretKey)) {
throw new TypeError('secretKey cannot use plainText');
}
return /^[a-zA-Z0-9]+$/i.test(secretKey);
}
static rotation(secretKey, token, rotate, rotateType) {
const tokenArr = token.split('.');
const firstToken = tokenArr[0];
const middleToken = tokenArr[1];
const lastToken = tokenArr[2];
let mergeToken = '';
if (rotateType === EJwtTransform.ENC) {
mergeToken = `${firstToken}.${middleToken}${secretKey}.${lastToken}`;
}
else {
mergeToken = `${firstToken}.${middleToken}.${lastToken}`;
}
let cleanupMergeToken = mergeToken.replace(/\s/g, '');
if (rotateType === 'decrypt') {
const encryptSecretKey = JwtTransform.getRotatedSecretKey(secretKey, Math.abs(rotate));
if (!cleanupMergeToken.includes(encryptSecretKey)) {
throw new Error('secretKey not match');
}
const validJwtToken = cleanupMergeToken.replace(new RegExp(encryptSecretKey, 'g'), '');
cleanupMergeToken = validJwtToken;
}
rotate %= JwtTransform.alphacount;
const text = Array.from(cleanupMergeToken);
const transformedText = text.map((v) => {
if (v >= 'a' && v <= 'z') {
return JwtTransform.lca[(26 + (v.charCodeAt(0) - 'a'.charCodeAt(0)) + rotate) % JwtTransform.alphacount];
}
else if (v >= 'A' && v <= 'Z') {
return JwtTransform.uca[(26 + (v.charCodeAt(0) - 'A'.charCodeAt(0)) + rotate) % JwtTransform.alphacount];
}
else {
return v;
}
});
return transformedText.join('');
}
static getRotatedSecretKey(secretKey, rotate) {
const cacheKey = `${secretKey}-${rotate}`;
if (JwtTransform.secretKeyCache[cacheKey]) {
return JwtTransform.secretKeyCache[cacheKey];
}
const text = Array.from(secretKey);
const rotatedText = text.map((v) => {
if (v >= 'a' && v <= 'z') {
return JwtTransform.lca[(26 + (v.charCodeAt(0) - 'a'.charCodeAt(0)) + rotate) % JwtTransform.alphacount];
}
else if (v >= 'A' && v <= 'Z') {
return JwtTransform.uca[(26 + (v.charCodeAt(0) - 'A'.charCodeAt(0)) + rotate) % JwtTransform.alphacount];
}
else {
return v;
}
});
const rotatedSecretKey = rotatedText.join('');
JwtTransform.secretKeyCache[cacheKey] = rotatedSecretKey;
return rotatedSecretKey;
}
static transform(secretKey, plainText, rotate) {
try {
JwtTransform.validSecretKey(secretKey, plainText, rotate, EJwtTransform.DEC);
return JwtTransform.rotation(secretKey, plainText, rotate, EJwtTransform.ENC);
}
catch (e) {
throw new TypeError(e);
}
}
static untransform(secretKey, cipherText, rotate) {
try {
JwtTransform.validSecretKey(secretKey, cipherText, rotate, EJwtTransform.DEC);
return JwtTransform.rotation(secretKey, cipherText, -rotate, EJwtTransform.DEC);
}
catch (e) {
throw new TypeError(e);
}
}
}
exports.JwtTransform = JwtTransform;
});