@carecard/auth-util 3.1.15 → 3.2.0
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/.agents/skills/carecard-workspace-standards/SKILL.md +30 -17
- package/.agents/skills/github-pr-create-update/SKILL.md +63 -84
- package/.agents/skills/github-pr-merge-cleanup/SKILL.md +103 -79
- package/.agents/skills/npm-package-flow/SKILL.md +75 -0
- package/.agents/skills/npm-package-flow/agents/openai.yaml +5 -0
- package/.agents/skills/pkg-auth-util-auth-crypto-library/SKILL.md +8 -5
- package/.agents/skills/software-design-patterns-and-clean-code/SKILL.md +1 -1
- package/package.json +7 -7
- package/readme.md +13 -0
- package/.prettierignore +0 -17
- package/.prettierrc.cjs +0 -32
- package/jest.config.js +0 -16
- package/scripts/rename-cjs.js +0 -13
- package/src/cryptoUtilAuth.ts +0 -111
- package/src/index.ts +0 -6
- package/src/jwtUtilAuth.ts +0 -85
- package/src/keyGen.ts +0 -14
- package/src/pwdUtilAuth.ts +0 -78
- package/src/strEncryptUtil.ts +0 -159
- package/src/stringUtilAuth.ts +0 -102
- package/tests/cryptoUtilAuth.test.ts +0 -97
- package/tests/index.test.ts +0 -157
- package/tests/indexStringUtilAuth.test.ts +0 -95
- package/tests/jwtUtilAuth.test.ts +0 -33
- package/tests/keyGen.test.ts +0 -26
- package/tests/keys/keys.ts +0 -24
- package/tests/pwdUtilAuth.test.ts +0 -40
- package/tsconfig.base.json +0 -14
- package/tsconfig.cjs.json +0 -7
- package/tsconfig.esm.json +0 -7
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: npm-package-flow
|
|
3
|
+
description: 'Use in pkg-* repositories when publishable package code changes require a version bump, GitHub development/main squash-merge flow, npm publication, and uncommitted consumer package updates in ms-* and app-dashboard.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# npm Package Flow
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Use this skill in a `pkg-*` repository when package code changes need to be
|
|
11
|
+
published to npm and propagated to CareCard consumers.
|
|
12
|
+
|
|
13
|
+
The package name is the `name` field in the repository `package.json`.
|
|
14
|
+
|
|
15
|
+
## Publishable vs Non-Publishable Changes
|
|
16
|
+
|
|
17
|
+
Publishable package changes include runtime source changes, public exports,
|
|
18
|
+
TypeScript declarations, package metadata that affects consumers, security
|
|
19
|
+
behavior, or dependency behavior that changes the package contract.
|
|
20
|
+
|
|
21
|
+
The following are not publishable package changes by themselves:
|
|
22
|
+
|
|
23
|
+
- Skills or `.agents` guidance.
|
|
24
|
+
- Documentation and README updates.
|
|
25
|
+
- Tests, fixtures, mocks, snapshots, or validation-only changes.
|
|
26
|
+
- Formatting-only changes and comments.
|
|
27
|
+
|
|
28
|
+
For non-publishable changes, do not bump the package version, publish to npm,
|
|
29
|
+
or update `ms-*` and `app-dashboard` package versions.
|
|
30
|
+
|
|
31
|
+
## Required Flow For Publishable Changes
|
|
32
|
+
|
|
33
|
+
Run this workflow only when the user explicitly asks for package publication,
|
|
34
|
+
remote GitHub merge work, or the full package-flow completion. Remote Git and
|
|
35
|
+
GitHub operations must not be inferred.
|
|
36
|
+
|
|
37
|
+
1. Finish package code, tests, documentation, and skill updates inside the
|
|
38
|
+
current `pkg-*` repository.
|
|
39
|
+
2. Bump the package version in `package.json` and `package-lock.json` according
|
|
40
|
+
to the user request or the package change scope.
|
|
41
|
+
3. Run the package's required tests, lint, type checks, and every direct Husky
|
|
42
|
+
script. Fix failures before continuing.
|
|
43
|
+
4. Commit the package changes to the current branch.
|
|
44
|
+
5. Push the current branch, create or reuse the PR into `development`,
|
|
45
|
+
squash-merge it with administrator privileges, and delete the merged branch.
|
|
46
|
+
6. Create a new merge branch from the updated `development` branch and use that
|
|
47
|
+
branch to open a PR into `main`.
|
|
48
|
+
7. Squash-merge the merge branch into `main` with administrator privileges and
|
|
49
|
+
delete the merge branch. This `main` merge publishes the package.
|
|
50
|
+
8. Confirm publication with `npm view <package-name>@<version> version`.
|
|
51
|
+
9. Check out a fresh local branch with the same name as the deleted working
|
|
52
|
+
branch from the updated `development` branch.
|
|
53
|
+
10. Update the new `@carecard/...` package version in `app-dashboard` and in
|
|
54
|
+
only the `ms-*` repositories that already declare the package, plus any
|
|
55
|
+
explicitly intended new consumers.
|
|
56
|
+
11. Run `npm install` and relevant validation in each updated consumer.
|
|
57
|
+
12. Do not commit the `ms-*` or `app-dashboard` consumer updates unless the user
|
|
58
|
+
explicitly asks.
|
|
59
|
+
|
|
60
|
+
## Consumer Update Rules
|
|
61
|
+
|
|
62
|
+
- Discover existing consumers by checking each target repository `package.json`
|
|
63
|
+
for the published package name.
|
|
64
|
+
- Install exact package versions, for example
|
|
65
|
+
`npm install <package-name>@<version> --save-exact`.
|
|
66
|
+
- Keep consumer updates local and uncommitted unless the user gives a separate
|
|
67
|
+
commit or PR instruction.
|
|
68
|
+
- If a consumer should become a new dependency, require explicit user intent for
|
|
69
|
+
that repository.
|
|
70
|
+
|
|
71
|
+
## Reporting
|
|
72
|
+
|
|
73
|
+
Report the package name, published version, development PR, main PR, npm
|
|
74
|
+
publication check, consumer repositories updated, validation commands run, and
|
|
75
|
+
any consumer updates intentionally left uncommitted.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: 'npm Package Flow'
|
|
3
|
+
short_description: 'Use in pkg-* repositories when publishable @carecard package code changes need npm publication and consumer updates.'
|
|
4
|
+
brand_color: '#0F766E'
|
|
5
|
+
default_prompt: 'Use $npm-package-flow when this task matches the skill scope.'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pkg-auth-util-auth-crypto-library
|
|
3
|
-
description: Use when changing pkg-auth-util auth, password, JWT, crypto, key, exported API, types, or package validation behavior.
|
|
3
|
+
description: 'Use when changing pkg-auth-util auth, password, JWT, crypto, key, exported API, types, or package validation behavior.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Package Auth Util
|
|
@@ -43,8 +43,8 @@ CareCard auth utility package for JWT creation/verification primitives, password
|
|
|
43
43
|
|
|
44
44
|
## Safety Constraints
|
|
45
45
|
|
|
46
|
-
- Do not edit generated output, dependency folders, logs, coverage, dist, or build artifacts unless the task
|
|
47
|
-
- Do not revert or overwrite user changes; stage only
|
|
46
|
+
- Do not edit generated output, dependency folders, logs, coverage, dist, or build artifacts unless the task requires it.
|
|
47
|
+
- Do not revert or overwrite user changes; stage only requested skill or instruction files.
|
|
48
48
|
- Never suppress errors, lint failures, type failures, security failures, or failing tests; fix the underlying issue or report the blocker.
|
|
49
49
|
- Do not log or expose secrets, JWTs, passwords, credentials, private keys, sensitive personal data, SQL internals, or stack traces.
|
|
50
50
|
|
|
@@ -107,6 +107,9 @@ depend on those folders being present.
|
|
|
107
107
|
`jwtCreateServiceAuthorizationHeader`.
|
|
108
108
|
- Do not silently change token timing behavior, token formats, JWT string
|
|
109
109
|
assembly, signature verification semantics, or decomposition return shapes.
|
|
110
|
+
- Preserve application JWT payload claims, including the `roles` array.
|
|
111
|
+
`ms-auth` RLS treats `roles: ["ad"]` as the auth-service super-admin signal,
|
|
112
|
+
so JWT helpers must not hide, rename, or drop that role data.
|
|
110
113
|
- Expected parse and verify failures should return `null` or `false` where the
|
|
111
114
|
current public API does so.
|
|
112
115
|
|
|
@@ -146,7 +149,7 @@ depend on those folders being present.
|
|
|
146
149
|
- Use `try/catch` inside utility functions where existing functions fail
|
|
147
150
|
gracefully instead of throwing uncaught exceptions.
|
|
148
151
|
- Do not broaden catch blocks in a way that hides unexpected implementation
|
|
149
|
-
errors in callers that
|
|
152
|
+
errors in callers that expect throws.
|
|
150
153
|
|
|
151
154
|
## Types And Exports
|
|
152
155
|
|
|
@@ -199,7 +202,7 @@ and remaining risk.
|
|
|
199
202
|
|
|
200
203
|
## Remote Git Operations Guardrail
|
|
201
204
|
|
|
202
|
-
Do not run remote Git or GitHub operations unless the current user request explicitly asks for
|
|
205
|
+
Do not run remote Git or GitHub operations unless the current user request explicitly asks for them. This includes `git fetch`, `git pull`, `git push`, `git push --delete`, remote branch cleanup, GitHub API calls, and any `gh pr` command that creates, updates, readies, merges, closes, or cleans up a pull request. Do not infer permission from branch names, validation needs, prior workflow habits, or convenience; ask first when remote state would help but was not requested.
|
|
203
206
|
|
|
204
207
|
## Agent Guidance Git Workflow
|
|
205
208
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: software-design-patterns-and-clean-code
|
|
3
|
-
description: Use every time before coding, refactoring, debugging, or reviewing in this repository, alongside all other applicable skills, to apply pragmatic software design patterns, SOLID, Clean Code, and testable architecture.
|
|
3
|
+
description: 'Use every time before coding, refactoring, debugging, or reviewing in this repository, alongside all other applicable skills, to apply pragmatic software design patterns, SOLID, Clean Code, and testable architecture.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Software Design Patterns And Clean Code
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carecard/auth-util",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"repository": "https://github.com/CareCard-ca/pkg-auth-util.git",
|
|
5
5
|
"description": "Auth utility functions",
|
|
6
6
|
"main": "index.js",
|
|
@@ -25,24 +25,24 @@
|
|
|
25
25
|
"author": "CareCard team",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"express": "5.2.1",
|
|
29
28
|
"@istanbuljs/nyc-config-typescript": "1.0.2",
|
|
29
|
+
"@types/express": "5.0.6",
|
|
30
30
|
"@types/mocha": "10.0.10",
|
|
31
31
|
"@types/node": "25.9.1",
|
|
32
|
-
"
|
|
32
|
+
"eslint": "9.39.4",
|
|
33
|
+
"express": "5.2.1",
|
|
33
34
|
"husky": "9.1.7",
|
|
35
|
+
"lint-staged": "17.0.5",
|
|
34
36
|
"mocha": "11.7.6",
|
|
35
37
|
"nyc": "18.0.0",
|
|
36
38
|
"prettier": "3.8.3",
|
|
37
|
-
"eslint": "9.39.4",
|
|
38
|
-
"lint-staged": "17.0.5",
|
|
39
39
|
"source-map-support": "0.5.21",
|
|
40
40
|
"supertest": "7.2.2",
|
|
41
41
|
"ts-node": "10.9.2",
|
|
42
42
|
"typescript": "6.0.3"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@carecard/common-util": "3.
|
|
46
|
-
"@carecard/validate": "3.
|
|
45
|
+
"@carecard/common-util": "3.2.0",
|
|
46
|
+
"@carecard/validate": "3.3.0"
|
|
47
47
|
}
|
|
48
48
|
}
|
package/readme.md
CHANGED
|
@@ -100,6 +100,19 @@ const urlSafe = stringUtilAuth.makeStringUrlSafe('a+b/c==');
|
|
|
100
100
|
// Result: a-b_c
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
## CareCard Auth Contract
|
|
104
|
+
|
|
105
|
+
`ms-auth` issues CareCard user JWTs and now enforces its own auth tables with
|
|
106
|
+
forced PostgreSQL RLS. This package should preserve JWT claim values exactly
|
|
107
|
+
when creating or verifying tokens; a payload containing `roles: ["ad"]` is the
|
|
108
|
+
auth-service super-admin signal. Do not add helpers that hide, rename, or drop
|
|
109
|
+
the `roles` array, and do not add database bypass behavior to this package.
|
|
110
|
+
|
|
111
|
+
Docs that mention `ms-auth` controller internals should use concise action
|
|
112
|
+
names such as `loginUser`, `registerUser`, `getUserDetail`, and `renewJwt`.
|
|
113
|
+
Access level is conveyed by route middleware and endpoint placement, not by
|
|
114
|
+
`public`/`protected`/`admin`/`Handler` suffixes.
|
|
115
|
+
|
|
103
116
|
## Testing
|
|
104
117
|
|
|
105
118
|
Run tests using:
|
package/.prettierignore
DELETED
package/.prettierrc.cjs
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/** @type {import('prettier').Config} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
// Core formatting
|
|
4
|
-
printWidth: 100,
|
|
5
|
-
tabWidth: 2,
|
|
6
|
-
useTabs: false,
|
|
7
|
-
semi: true,
|
|
8
|
-
singleQuote: true,
|
|
9
|
-
trailingComma: 'all',
|
|
10
|
-
bracketSpacing: true,
|
|
11
|
-
bracketSameLine: true,
|
|
12
|
-
arrowParens: 'avoid',
|
|
13
|
-
|
|
14
|
-
// Line endings (important for cross-platform + CI)
|
|
15
|
-
endOfLine: 'auto',
|
|
16
|
-
|
|
17
|
-
// Language-specific overrides
|
|
18
|
-
overrides: [
|
|
19
|
-
{
|
|
20
|
-
files: '*.json',
|
|
21
|
-
options: {
|
|
22
|
-
printWidth: 80,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
files: '*.md',
|
|
27
|
-
options: {
|
|
28
|
-
proseWrap: 'preserve',
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
};
|
package/jest.config.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
preset: 'ts-jest',
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
transform: {
|
|
5
|
-
'^.+\\.ts$': [
|
|
6
|
-
'ts-jest',
|
|
7
|
-
{
|
|
8
|
-
tsconfig: 'tsconfig.base.json',
|
|
9
|
-
},
|
|
10
|
-
],
|
|
11
|
-
},
|
|
12
|
-
testMatch: ['**/tests/**/*.test.ts'],
|
|
13
|
-
collectCoverage: true,
|
|
14
|
-
collectCoverageFrom: ['src/**/*.ts'],
|
|
15
|
-
coverageDirectory: 'coverage'
|
|
16
|
-
};
|
package/scripts/rename-cjs.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
const dir = './dist/cjs';
|
|
5
|
-
|
|
6
|
-
for (const file of fs.readdirSync(dir)) {
|
|
7
|
-
if (file.endsWith('.js')) {
|
|
8
|
-
fs.renameSync(
|
|
9
|
-
path.join(dir, file),
|
|
10
|
-
path.join(dir, file.replace('.js', '.cjs'))
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
}
|
package/src/cryptoUtilAuth.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import * as crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Signs a token returns signature string
|
|
5
|
-
* @param token
|
|
6
|
-
* @param privateKey
|
|
7
|
-
* @param signingAlgorithm
|
|
8
|
-
* @returns {string}
|
|
9
|
-
*/
|
|
10
|
-
export const createBase64SignatureOfToken = function (
|
|
11
|
-
token: string = '',
|
|
12
|
-
privateKey: string,
|
|
13
|
-
signingAlgorithm: string,
|
|
14
|
-
): string {
|
|
15
|
-
const sign = crypto.createSign(signingAlgorithm);
|
|
16
|
-
sign.write(token);
|
|
17
|
-
sign.end();
|
|
18
|
-
return sign.sign(privateKey, 'base64');
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Verifies the signature returns true or false
|
|
23
|
-
* @param token
|
|
24
|
-
* @param signature
|
|
25
|
-
* @param publicKey
|
|
26
|
-
* @param signingAlgorithm
|
|
27
|
-
* @returns {boolean}
|
|
28
|
-
*/
|
|
29
|
-
export const verifyBase64SignatureOfToken = function (
|
|
30
|
-
token: string = '',
|
|
31
|
-
signature: string,
|
|
32
|
-
publicKey: string,
|
|
33
|
-
signingAlgorithm: string,
|
|
34
|
-
): boolean {
|
|
35
|
-
const verify = crypto.createVerify(signingAlgorithm);
|
|
36
|
-
verify.update(token);
|
|
37
|
-
verify.end();
|
|
38
|
-
return verify.verify(publicKey, signature, 'base64');
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Creates the hash of given string
|
|
43
|
-
* @param string
|
|
44
|
-
* @param secret
|
|
45
|
-
* @param algorithm
|
|
46
|
-
* @returns {string}
|
|
47
|
-
*/
|
|
48
|
-
export const createHmacBase64 = function (
|
|
49
|
-
string: string = '',
|
|
50
|
-
secret: string,
|
|
51
|
-
algorithm: string,
|
|
52
|
-
): string {
|
|
53
|
-
const hmac = crypto.createHmac(algorithm, secret);
|
|
54
|
-
hmac.update(string);
|
|
55
|
-
return hmac.digest('base64');
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Create random salt
|
|
60
|
-
* @returns {string}
|
|
61
|
-
*/
|
|
62
|
-
export const createSaltBase64 = (): string => {
|
|
63
|
-
const date = new Date().valueOf();
|
|
64
|
-
const hmac = crypto.createHmac('SHA256', date.toString());
|
|
65
|
-
hmac.update(date.toString());
|
|
66
|
-
return hmac.digest('base64');
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Encrypt given string
|
|
71
|
-
* @param string
|
|
72
|
-
* @param salt
|
|
73
|
-
* @param secret
|
|
74
|
-
* @param algorithm
|
|
75
|
-
* @returns {string}
|
|
76
|
-
*/
|
|
77
|
-
export const encryptStringAsciiToBase64 = (
|
|
78
|
-
string: string,
|
|
79
|
-
salt: string,
|
|
80
|
-
secret: string,
|
|
81
|
-
algorithm: string,
|
|
82
|
-
): string => {
|
|
83
|
-
const key = crypto.scryptSync(secret, salt, 24);
|
|
84
|
-
const iv = Buffer.alloc(16, 0);
|
|
85
|
-
const cipher = crypto.createCipheriv(algorithm, key, iv);
|
|
86
|
-
let encrypted = cipher.update(string, 'ascii', 'base64');
|
|
87
|
-
encrypted += cipher.final('base64');
|
|
88
|
-
return encrypted;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Decrypts given string
|
|
93
|
-
* @param encryptedString
|
|
94
|
-
* @param salt
|
|
95
|
-
* @param secret
|
|
96
|
-
* @param algorithm
|
|
97
|
-
* @returns {string}
|
|
98
|
-
*/
|
|
99
|
-
export const decryptStringBase64ToAscii = (
|
|
100
|
-
encryptedString: string,
|
|
101
|
-
salt: string,
|
|
102
|
-
secret: string,
|
|
103
|
-
algorithm: string,
|
|
104
|
-
): string => {
|
|
105
|
-
const key = crypto.scryptSync(secret, salt, 24);
|
|
106
|
-
const iv = Buffer.alloc(16, 0);
|
|
107
|
-
const decipher = crypto.createDecipheriv(algorithm, key, iv);
|
|
108
|
-
let decrypted = decipher.update(encryptedString, 'base64', 'ascii');
|
|
109
|
-
decrypted += decipher.final('ascii');
|
|
110
|
-
return decrypted;
|
|
111
|
-
};
|
package/src/index.ts
DELETED
package/src/jwtUtilAuth.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import * as stringUtilAuth from './stringUtilAuth';
|
|
2
|
-
import * as cryptoUtilAuth from './cryptoUtilAuth';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* User supplied header, payload and signature create jwt.
|
|
6
|
-
* @returns {string|null}
|
|
7
|
-
* @param headerBase64
|
|
8
|
-
* @param payloadBase64
|
|
9
|
-
* @param signatureBase64
|
|
10
|
-
*/
|
|
11
|
-
export const _assembleJwt = (
|
|
12
|
-
headerBase64: string,
|
|
13
|
-
payloadBase64: string,
|
|
14
|
-
signatureBase64: string,
|
|
15
|
-
): string => {
|
|
16
|
-
return headerBase64 + '.' + payloadBase64 + '.' + signatureBase64;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* User supplied header, payload and signature create jwt.
|
|
21
|
-
* @returns {{payload: *, signature: *, header: *}}
|
|
22
|
-
* @param jwt
|
|
23
|
-
*/
|
|
24
|
-
export const _splitJwtInToHeaderPayloadSignature = (jwt: string): any => {
|
|
25
|
-
return stringUtilAuth.dotConnectedStringToHeaderPayloadSignature(jwt);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Creates Url safe jwt
|
|
30
|
-
* @param headerObject
|
|
31
|
-
* @param payloadObject
|
|
32
|
-
* @param privateKey
|
|
33
|
-
* @return {string|null}
|
|
34
|
-
*/
|
|
35
|
-
export const createSignedJwtFromObject = (
|
|
36
|
-
headerObject: any,
|
|
37
|
-
payloadObject: any,
|
|
38
|
-
privateKey: string,
|
|
39
|
-
): any => {
|
|
40
|
-
try {
|
|
41
|
-
const algorithm = headerObject.alg;
|
|
42
|
-
const headerBase64UrlSafe = stringUtilAuth.objectToBase64UrlSafeString(headerObject);
|
|
43
|
-
const payloadBase64UrlSafe = stringUtilAuth.objectToBase64UrlSafeString(payloadObject);
|
|
44
|
-
const token = headerBase64UrlSafe + '.' + payloadBase64UrlSafe;
|
|
45
|
-
const signature = cryptoUtilAuth.createBase64SignatureOfToken(token, privateKey, algorithm);
|
|
46
|
-
const urlSafeSignature = stringUtilAuth.makeStringUrlSafe(signature);
|
|
47
|
-
return _assembleJwt(headerBase64UrlSafe, payloadBase64UrlSafe, urlSafeSignature);
|
|
48
|
-
} catch (error) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Verify signature of jwt
|
|
55
|
-
* @param jwt
|
|
56
|
-
* @param publicKey
|
|
57
|
-
* @return {boolean}
|
|
58
|
-
*/
|
|
59
|
-
export const verifyJwtSignature = (jwt: string, publicKey: string): boolean => {
|
|
60
|
-
try {
|
|
61
|
-
const { header, payload, signature } = _splitJwtInToHeaderPayloadSignature(jwt);
|
|
62
|
-
const token = header + '.' + payload;
|
|
63
|
-
const headerObject = stringUtilAuth.urlSafeBase64ToObject(header);
|
|
64
|
-
return cryptoUtilAuth.verifyBase64SignatureOfToken(
|
|
65
|
-
token,
|
|
66
|
-
signature,
|
|
67
|
-
publicKey,
|
|
68
|
-
headerObject.alg,
|
|
69
|
-
);
|
|
70
|
-
} catch (error) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Returns header and payload object for jwt.
|
|
77
|
-
* @param jwt
|
|
78
|
-
* @return {{payload: any, header: any}}
|
|
79
|
-
*/
|
|
80
|
-
export const getHeaderPayloadFromJwt = (jwt: string): any => {
|
|
81
|
-
const { header, payload } = _splitJwtInToHeaderPayloadSignature(jwt);
|
|
82
|
-
let headerAscii = stringUtilAuth.base64ToAscii(header);
|
|
83
|
-
let payloadAscii = stringUtilAuth.base64ToAscii(payload);
|
|
84
|
-
return { header: JSON.parse(headerAscii), payload: JSON.parse(payloadAscii) };
|
|
85
|
-
};
|
package/src/keyGen.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { generateKeyPairSync } from 'node:crypto';
|
|
2
|
-
|
|
3
|
-
export const generateKeyPair = (modulusLength: number = 4096) =>
|
|
4
|
-
generateKeyPairSync('rsa', {
|
|
5
|
-
modulusLength: modulusLength,
|
|
6
|
-
publicKeyEncoding: {
|
|
7
|
-
type: 'spki',
|
|
8
|
-
format: 'pem',
|
|
9
|
-
},
|
|
10
|
-
privateKeyEncoding: {
|
|
11
|
-
type: 'pkcs8',
|
|
12
|
-
format: 'pem',
|
|
13
|
-
},
|
|
14
|
-
});
|
package/src/pwdUtilAuth.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import * as cryptoUtilAuth from './cryptoUtilAuth';
|
|
2
|
-
import * as stringUtilAuth from './stringUtilAuth';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Just assemble password together
|
|
6
|
-
* @param algorithmBase64
|
|
7
|
-
* @param hashBase64
|
|
8
|
-
* @param saltBase64
|
|
9
|
-
* @return {string}
|
|
10
|
-
*/
|
|
11
|
-
export const _assemblePasswordHash = (
|
|
12
|
-
algorithmBase64: string,
|
|
13
|
-
hashBase64: string,
|
|
14
|
-
saltBase64: string,
|
|
15
|
-
): string => {
|
|
16
|
-
return '$1$' + algorithmBase64 + '$' + hashBase64 + '$' + saltBase64 + '$';
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Break password into its parts does not reverse base64 encoding.
|
|
21
|
-
* @param passwordHashStored
|
|
22
|
-
* @return {{salt: *, version: *, alg: *, hash: *}}
|
|
23
|
-
*/
|
|
24
|
-
export const _disassemblePasswordHash = (passwordHashStored: string): any => {
|
|
25
|
-
return stringUtilAuth.dollarSignConnectedStringToAlgorithmHashSalt(passwordHashStored);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Creates password hash ready to be saved in database.
|
|
30
|
-
* @param password
|
|
31
|
-
* @param secret
|
|
32
|
-
* @param salt
|
|
33
|
-
* @param algorithm
|
|
34
|
-
* @return {string}
|
|
35
|
-
*/
|
|
36
|
-
export const _createPasswordHash = (
|
|
37
|
-
password: string,
|
|
38
|
-
secret: string,
|
|
39
|
-
salt: string,
|
|
40
|
-
algorithm: string,
|
|
41
|
-
): string => {
|
|
42
|
-
const algorithmBase64 = stringUtilAuth.asciiToBase64(algorithm);
|
|
43
|
-
const hashBase64 = cryptoUtilAuth.createHmacBase64(password, secret, algorithm);
|
|
44
|
-
return _assemblePasswordHash(algorithmBase64, hashBase64, salt);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Automatically adds random salt.
|
|
49
|
-
* @param password
|
|
50
|
-
* @param secret
|
|
51
|
-
* @param algorithm
|
|
52
|
-
* @return {string}
|
|
53
|
-
*/
|
|
54
|
-
export const createPasswordHashWithRandomSalt = (
|
|
55
|
-
password: string,
|
|
56
|
-
secret: string,
|
|
57
|
-
algorithm: string,
|
|
58
|
-
): string => {
|
|
59
|
-
const salt = cryptoUtilAuth.createSaltBase64();
|
|
60
|
-
return _createPasswordHash(password, secret, salt, algorithm);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Creates hash based on saved hash in database.
|
|
65
|
-
* @param password
|
|
66
|
-
* @param savedPasswordHash
|
|
67
|
-
* @param secret
|
|
68
|
-
* @return {string}
|
|
69
|
-
*/
|
|
70
|
-
export const createPasswordHashBasedOnSavedAlgorithmSalt = (
|
|
71
|
-
password: string,
|
|
72
|
-
savedPasswordHash: string,
|
|
73
|
-
secret: string,
|
|
74
|
-
): string => {
|
|
75
|
-
const { alg, salt } = _disassemblePasswordHash(savedPasswordHash);
|
|
76
|
-
const algorithm = stringUtilAuth.base64ToAscii(alg);
|
|
77
|
-
return _createPasswordHash(password, secret, salt, algorithm);
|
|
78
|
-
};
|