@alphacifer/authkit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/hash/index.cjs +46 -0
- package/lib/hash/index.d.cts +25 -0
- package/lib/hash/index.d.mts +25 -0
- package/lib/hash/index.mjs +43 -0
- package/lib/jwt.cjs +53 -0
- package/lib/jwt.d.cts +43 -0
- package/lib/jwt.d.mts +43 -0
- package/lib/jwt.mjs +27 -0
- package/package.json +54 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../jwt.cjs");
|
|
3
|
+
let node_crypto = require("node:crypto");
|
|
4
|
+
let node_util = require("node:util");
|
|
5
|
+
//#region src/hash/index.ts
|
|
6
|
+
const asyncArgon2 = (0, node_util.promisify)(node_crypto.argon2);
|
|
7
|
+
const asyncRandomBytes = (0, node_util.promisify)(node_crypto.randomBytes);
|
|
8
|
+
async function passwordHash({ password, passes = 3, tagLength = 32, parallelism = 4, memory = 65534 }) {
|
|
9
|
+
const salt = await asyncRandomBytes(16);
|
|
10
|
+
const hash = await asyncArgon2("argon2id", {
|
|
11
|
+
memory,
|
|
12
|
+
passes,
|
|
13
|
+
tagLength,
|
|
14
|
+
parallelism,
|
|
15
|
+
nonce: salt,
|
|
16
|
+
message: password
|
|
17
|
+
});
|
|
18
|
+
return `$argon2id$v=19$m=${memory},t=${passes},p=${parallelism}$${salt.toString("base64").replace(/=+$/, "")}$${hash.toString("base64").replace(/=+$/, "")}`;
|
|
19
|
+
}
|
|
20
|
+
async function verifyPassword({ password, hashPassword }) {
|
|
21
|
+
try {
|
|
22
|
+
const parts = hashPassword.split("$");
|
|
23
|
+
if (parts.length !== 6 || parts[1] !== "argon2id") return false;
|
|
24
|
+
const [, , , params, saltB64, hashB64] = parts;
|
|
25
|
+
const paramMatch = params?.match(/m=(\d+),t=(\d+),p=(\d+)/);
|
|
26
|
+
if (!paramMatch) return false;
|
|
27
|
+
const memory = Number.parseInt(paramMatch[1] || "", 10);
|
|
28
|
+
const passes = Number.parseInt(paramMatch[2] || "", 10);
|
|
29
|
+
const parallelism = Number.parseInt(paramMatch[3] || "", 10);
|
|
30
|
+
const salt = Buffer.from(saltB64 || "", "base64");
|
|
31
|
+
const originalHash = Buffer.from(hashB64 || "", "base64");
|
|
32
|
+
return (0, node_crypto.timingSafeEqual)(originalHash, await asyncArgon2("argon2id", {
|
|
33
|
+
memory,
|
|
34
|
+
passes,
|
|
35
|
+
parallelism,
|
|
36
|
+
nonce: salt,
|
|
37
|
+
message: password,
|
|
38
|
+
tagLength: originalHash.length
|
|
39
|
+
}));
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
exports.passwordHash = passwordHash;
|
|
46
|
+
exports.verifyPassword = verifyPassword;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/hash/index.d.ts
|
|
2
|
+
interface IPasswordHashParams {
|
|
3
|
+
memory?: number;
|
|
4
|
+
passes?: number;
|
|
5
|
+
password: string;
|
|
6
|
+
tagLength?: number;
|
|
7
|
+
parallelism?: number;
|
|
8
|
+
}
|
|
9
|
+
declare function passwordHash({
|
|
10
|
+
password,
|
|
11
|
+
passes,
|
|
12
|
+
tagLength,
|
|
13
|
+
parallelism,
|
|
14
|
+
memory
|
|
15
|
+
}: IPasswordHashParams): Promise<string>;
|
|
16
|
+
interface IVerifyPasswordParams {
|
|
17
|
+
password: string;
|
|
18
|
+
hashPassword: string;
|
|
19
|
+
}
|
|
20
|
+
declare function verifyPassword({
|
|
21
|
+
password,
|
|
22
|
+
hashPassword
|
|
23
|
+
}: IVerifyPasswordParams): Promise<boolean>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { passwordHash, verifyPassword };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/hash/index.d.ts
|
|
2
|
+
interface IPasswordHashParams {
|
|
3
|
+
memory?: number;
|
|
4
|
+
passes?: number;
|
|
5
|
+
password: string;
|
|
6
|
+
tagLength?: number;
|
|
7
|
+
parallelism?: number;
|
|
8
|
+
}
|
|
9
|
+
declare function passwordHash({
|
|
10
|
+
password,
|
|
11
|
+
passes,
|
|
12
|
+
tagLength,
|
|
13
|
+
parallelism,
|
|
14
|
+
memory
|
|
15
|
+
}: IPasswordHashParams): Promise<string>;
|
|
16
|
+
interface IVerifyPasswordParams {
|
|
17
|
+
password: string;
|
|
18
|
+
hashPassword: string;
|
|
19
|
+
}
|
|
20
|
+
declare function verifyPassword({
|
|
21
|
+
password,
|
|
22
|
+
hashPassword
|
|
23
|
+
}: IVerifyPasswordParams): Promise<boolean>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { passwordHash, verifyPassword };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { argon2, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
//#region src/hash/index.ts
|
|
4
|
+
const asyncArgon2 = promisify(argon2);
|
|
5
|
+
const asyncRandomBytes = promisify(randomBytes);
|
|
6
|
+
async function passwordHash({ password, passes = 3, tagLength = 32, parallelism = 4, memory = 65534 }) {
|
|
7
|
+
const salt = await asyncRandomBytes(16);
|
|
8
|
+
const hash = await asyncArgon2("argon2id", {
|
|
9
|
+
memory,
|
|
10
|
+
passes,
|
|
11
|
+
tagLength,
|
|
12
|
+
parallelism,
|
|
13
|
+
nonce: salt,
|
|
14
|
+
message: password
|
|
15
|
+
});
|
|
16
|
+
return `$argon2id$v=19$m=${memory},t=${passes},p=${parallelism}$${salt.toString("base64").replace(/=+$/, "")}$${hash.toString("base64").replace(/=+$/, "")}`;
|
|
17
|
+
}
|
|
18
|
+
async function verifyPassword({ password, hashPassword }) {
|
|
19
|
+
try {
|
|
20
|
+
const parts = hashPassword.split("$");
|
|
21
|
+
if (parts.length !== 6 || parts[1] !== "argon2id") return false;
|
|
22
|
+
const [, , , params, saltB64, hashB64] = parts;
|
|
23
|
+
const paramMatch = params?.match(/m=(\d+),t=(\d+),p=(\d+)/);
|
|
24
|
+
if (!paramMatch) return false;
|
|
25
|
+
const memory = Number.parseInt(paramMatch[1] || "", 10);
|
|
26
|
+
const passes = Number.parseInt(paramMatch[2] || "", 10);
|
|
27
|
+
const parallelism = Number.parseInt(paramMatch[3] || "", 10);
|
|
28
|
+
const salt = Buffer.from(saltB64 || "", "base64");
|
|
29
|
+
const originalHash = Buffer.from(hashB64 || "", "base64");
|
|
30
|
+
return timingSafeEqual(originalHash, await asyncArgon2("argon2id", {
|
|
31
|
+
memory,
|
|
32
|
+
passes,
|
|
33
|
+
parallelism,
|
|
34
|
+
nonce: salt,
|
|
35
|
+
message: password,
|
|
36
|
+
tagLength: originalHash.length
|
|
37
|
+
}));
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { passwordHash, verifyPassword };
|
package/lib/jwt.cjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let jsonwebtoken = require("jsonwebtoken");
|
|
25
|
+
jsonwebtoken = __toESM(jsonwebtoken);
|
|
26
|
+
let nanoid = require("nanoid");
|
|
27
|
+
//#region src/jwt.ts
|
|
28
|
+
function extractJWT({ token, issuer, subject, audience, secretKey, algorithms = ["HS256"] }) {
|
|
29
|
+
return jsonwebtoken.default.verify(token, secretKey || process.env.JWT_SECRET || "", {
|
|
30
|
+
issuer,
|
|
31
|
+
subject,
|
|
32
|
+
audience,
|
|
33
|
+
algorithms
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function genToken({ jwtId, issuer, subject, payload, audience, secretKey, expiresIn, notBefore, algorithm = "HS256" }) {
|
|
37
|
+
const options = {
|
|
38
|
+
algorithm,
|
|
39
|
+
expiresIn: expiresIn ?? 3600
|
|
40
|
+
};
|
|
41
|
+
if (notBefore) options.notBefore = notBefore;
|
|
42
|
+
return jsonwebtoken.default.sign({
|
|
43
|
+
...payload,
|
|
44
|
+
iss: issuer,
|
|
45
|
+
sub: subject,
|
|
46
|
+
aud: audience,
|
|
47
|
+
jti: jwtId ?? (0, nanoid.nanoid)(20)
|
|
48
|
+
}, secretKey || process.env.JWT_SECRET || "", options);
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
exports.__toESM = __toESM;
|
|
52
|
+
exports.extractJWT = extractJWT;
|
|
53
|
+
exports.genToken = genToken;
|
package/lib/jwt.d.cts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SignOptions, VerifyOptions } from "jsonwebtoken";
|
|
2
|
+
|
|
3
|
+
//#region src/jwt.d.ts
|
|
4
|
+
interface IExtractJWTParams {
|
|
5
|
+
token: string;
|
|
6
|
+
issuer?: string;
|
|
7
|
+
subject?: string;
|
|
8
|
+
secretKey?: string;
|
|
9
|
+
algorithms?: ('HS256' | 'HS512')[];
|
|
10
|
+
audience?: VerifyOptions['audience'];
|
|
11
|
+
}
|
|
12
|
+
declare function extractJWT<T = unknown>({
|
|
13
|
+
token,
|
|
14
|
+
issuer,
|
|
15
|
+
subject,
|
|
16
|
+
audience,
|
|
17
|
+
secretKey,
|
|
18
|
+
algorithms
|
|
19
|
+
}: IExtractJWTParams): T;
|
|
20
|
+
interface IGenTokenParams {
|
|
21
|
+
jwtId?: string;
|
|
22
|
+
issuer?: string;
|
|
23
|
+
subject?: string;
|
|
24
|
+
secretKey?: string;
|
|
25
|
+
algorithm?: 'HS256' | 'HS512';
|
|
26
|
+
audience?: VerifyOptions['audience'];
|
|
27
|
+
expiresIn?: SignOptions['expiresIn'];
|
|
28
|
+
notBefore?: SignOptions['notBefore'];
|
|
29
|
+
payload: Record<string, string | string[]>;
|
|
30
|
+
}
|
|
31
|
+
declare function genToken({
|
|
32
|
+
jwtId,
|
|
33
|
+
issuer,
|
|
34
|
+
subject,
|
|
35
|
+
payload,
|
|
36
|
+
audience,
|
|
37
|
+
secretKey,
|
|
38
|
+
expiresIn,
|
|
39
|
+
notBefore,
|
|
40
|
+
algorithm
|
|
41
|
+
}: IGenTokenParams): string;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { extractJWT, genToken };
|
package/lib/jwt.d.mts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SignOptions, VerifyOptions } from "jsonwebtoken";
|
|
2
|
+
|
|
3
|
+
//#region src/jwt.d.ts
|
|
4
|
+
interface IExtractJWTParams {
|
|
5
|
+
token: string;
|
|
6
|
+
issuer?: string;
|
|
7
|
+
subject?: string;
|
|
8
|
+
secretKey?: string;
|
|
9
|
+
algorithms?: ('HS256' | 'HS512')[];
|
|
10
|
+
audience?: VerifyOptions['audience'];
|
|
11
|
+
}
|
|
12
|
+
declare function extractJWT<T = unknown>({
|
|
13
|
+
token,
|
|
14
|
+
issuer,
|
|
15
|
+
subject,
|
|
16
|
+
audience,
|
|
17
|
+
secretKey,
|
|
18
|
+
algorithms
|
|
19
|
+
}: IExtractJWTParams): T;
|
|
20
|
+
interface IGenTokenParams {
|
|
21
|
+
jwtId?: string;
|
|
22
|
+
issuer?: string;
|
|
23
|
+
subject?: string;
|
|
24
|
+
secretKey?: string;
|
|
25
|
+
algorithm?: 'HS256' | 'HS512';
|
|
26
|
+
audience?: VerifyOptions['audience'];
|
|
27
|
+
expiresIn?: SignOptions['expiresIn'];
|
|
28
|
+
notBefore?: SignOptions['notBefore'];
|
|
29
|
+
payload: Record<string, string | string[]>;
|
|
30
|
+
}
|
|
31
|
+
declare function genToken({
|
|
32
|
+
jwtId,
|
|
33
|
+
issuer,
|
|
34
|
+
subject,
|
|
35
|
+
payload,
|
|
36
|
+
audience,
|
|
37
|
+
secretKey,
|
|
38
|
+
expiresIn,
|
|
39
|
+
notBefore,
|
|
40
|
+
algorithm
|
|
41
|
+
}: IGenTokenParams): string;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { extractJWT, genToken };
|
package/lib/jwt.mjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
3
|
+
//#region src/jwt.ts
|
|
4
|
+
function extractJWT({ token, issuer, subject, audience, secretKey, algorithms = ["HS256"] }) {
|
|
5
|
+
return jwt.verify(token, secretKey || process.env.JWT_SECRET || "", {
|
|
6
|
+
issuer,
|
|
7
|
+
subject,
|
|
8
|
+
audience,
|
|
9
|
+
algorithms
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function genToken({ jwtId, issuer, subject, payload, audience, secretKey, expiresIn, notBefore, algorithm = "HS256" }) {
|
|
13
|
+
const options = {
|
|
14
|
+
algorithm,
|
|
15
|
+
expiresIn: expiresIn ?? 3600
|
|
16
|
+
};
|
|
17
|
+
if (notBefore) options.notBefore = notBefore;
|
|
18
|
+
return jwt.sign({
|
|
19
|
+
...payload,
|
|
20
|
+
iss: issuer,
|
|
21
|
+
sub: subject,
|
|
22
|
+
aud: audience,
|
|
23
|
+
jti: jwtId ?? nanoid(20)
|
|
24
|
+
}, secretKey || process.env.JWT_SECRET || "", options);
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { extractJWT, genToken };
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alphacifer/authkit",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Auth Kit for Alpha's projects.",
|
|
5
|
+
"exports": {
|
|
6
|
+
"./hash": {
|
|
7
|
+
"import": {
|
|
8
|
+
"types": "./lib/hash/index.d.mts",
|
|
9
|
+
"default": "./lib/hash/index.mjs"
|
|
10
|
+
},
|
|
11
|
+
"require": {
|
|
12
|
+
"types": "./lib/hash/index.d.cts",
|
|
13
|
+
"default": "./lib/hash/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"./jwt": {
|
|
17
|
+
"import": {
|
|
18
|
+
"types": "./lib/jwt.d.mts",
|
|
19
|
+
"default": "./lib/jwt.mjs"
|
|
20
|
+
},
|
|
21
|
+
"require": {
|
|
22
|
+
"types": "./lib/jwt.d.cts",
|
|
23
|
+
"default": "./lib/jwt.cjs"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"alpha",
|
|
29
|
+
"dx",
|
|
30
|
+
"authkit"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public",
|
|
34
|
+
"registry": "https://registry.npmjs.org/"
|
|
35
|
+
},
|
|
36
|
+
"author": "Alpha",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/zgid123/alpha-dx.git"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"jsonwebtoken": "9.0.3",
|
|
44
|
+
"nanoid": "5.1.11"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/jsonwebtoken": "9.0.10",
|
|
48
|
+
"@types/node": "25.9.0"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"prepublish": "pnpm build",
|
|
52
|
+
"build": "tsdown"
|
|
53
|
+
}
|
|
54
|
+
}
|