@adonisjs/core 6.15.2 → 6.17.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/build/commands/test.js +4 -0
- package/build/providers/edge_provider.js +4 -2
- package/build/src/cli_formatters/routes_list.d.ts +1 -0
- package/build/src/cli_formatters/routes_list.js +12 -4
- package/build/src/helpers/main.d.ts +1 -0
- package/build/src/helpers/main.js +1 -0
- package/build/src/helpers/verification_token.d.ts +79 -0
- package/build/src/helpers/verification_token.js +98 -0
- package/package.json +9 -8
package/build/commands/test.js
CHANGED
|
@@ -80,6 +80,7 @@ export default class Test extends BaseCommand {
|
|
|
80
80
|
* Runs tests
|
|
81
81
|
*/
|
|
82
82
|
async run() {
|
|
83
|
+
process.env.NODE_ENV = 'test';
|
|
83
84
|
const assembler = await importAssembler(this.app);
|
|
84
85
|
if (!assembler) {
|
|
85
86
|
this.#logMissingDevelopmentDependency('@adonisjs/assembler');
|
|
@@ -108,6 +109,9 @@ export default class Test extends BaseCommand {
|
|
|
108
109
|
files: suite.files,
|
|
109
110
|
};
|
|
110
111
|
}),
|
|
112
|
+
env: {
|
|
113
|
+
NODE_ENV: 'test',
|
|
114
|
+
},
|
|
111
115
|
metaFiles: this.app.rcFile.metaFiles,
|
|
112
116
|
});
|
|
113
117
|
/**
|
|
@@ -64,9 +64,11 @@ export default class EdgeServiceProvider {
|
|
|
64
64
|
* explicit handler
|
|
65
65
|
*/
|
|
66
66
|
BriskRoute.macro('render', function (template, data) {
|
|
67
|
-
|
|
67
|
+
function rendersTemplate({ view }) {
|
|
68
68
|
return view.render(template, data);
|
|
69
|
-
}
|
|
69
|
+
}
|
|
70
|
+
Object.defineProperty(rendersTemplate, 'listArgs', { value: template, writable: false });
|
|
71
|
+
return this.setHandler(rendersTemplate);
|
|
70
72
|
});
|
|
71
73
|
edge.use(pluginEdgeDumper(dumper));
|
|
72
74
|
}
|
|
@@ -129,6 +129,7 @@ export class RoutesListFormatter {
|
|
|
129
129
|
return {
|
|
130
130
|
type: 'closure',
|
|
131
131
|
name: handler.name || 'closure',
|
|
132
|
+
args: 'listArgs' in handler ? String(handler.listArgs) : undefined,
|
|
132
133
|
};
|
|
133
134
|
}
|
|
134
135
|
/**
|
|
@@ -178,15 +179,22 @@ export class RoutesListFormatter {
|
|
|
178
179
|
* Formats controller name for the ansi list and table
|
|
179
180
|
*/
|
|
180
181
|
#formatControllerName(route) {
|
|
181
|
-
return route.handler.type === 'controller'
|
|
182
|
+
return route.handler.type === 'controller'
|
|
183
|
+
? ` ${this.#colors.cyan(route.handler.moduleNameOrPath)}.`
|
|
184
|
+
: '';
|
|
182
185
|
}
|
|
183
186
|
/**
|
|
184
187
|
* Formats action name for the ansi list and table
|
|
185
188
|
*/
|
|
186
189
|
#formatAction(route) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
if (route.handler.type === 'controller') {
|
|
191
|
+
return `${this.#colors.cyan(route.handler.method)}`;
|
|
192
|
+
}
|
|
193
|
+
const functionName = ` ${this.#colors.cyan(route.handler.name)}`;
|
|
194
|
+
if (route.handler.args) {
|
|
195
|
+
return ` ${functionName}${this.#colors.dim(`(${route.handler.args})`)}`;
|
|
196
|
+
}
|
|
197
|
+
return functionName;
|
|
190
198
|
}
|
|
191
199
|
/**
|
|
192
200
|
* Formats route middleware for the ansi list and table
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { parseImports } from 'parse-imports';
|
|
2
2
|
export { createId as cuid, isCuid } from '@paralleldrive/cuid2';
|
|
3
3
|
export { slash, base64, compose, Secret, joinToURL, fsReadAll, safeEqual, getDirname, getFilename, fsImportAll, MessageBuilder, } from '@poppinss/utils';
|
|
4
|
+
export { VerificationToken } from './verification_token.js';
|
|
4
5
|
export { parseBindingReference } from './parse_binding_reference.js';
|
|
@@ -9,4 +9,5 @@
|
|
|
9
9
|
export { parseImports } from 'parse-imports';
|
|
10
10
|
export { createId as cuid, isCuid } from '@paralleldrive/cuid2';
|
|
11
11
|
export { slash, base64, compose, Secret, joinToURL, fsReadAll, safeEqual, getDirname, getFilename, fsImportAll, MessageBuilder, } from '@poppinss/utils';
|
|
12
|
+
export { VerificationToken } from './verification_token.js';
|
|
12
13
|
export { parseBindingReference } from './parse_binding_reference.js';
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Secret } from '@poppinss/utils';
|
|
2
|
+
/**
|
|
3
|
+
* Verification token class can be used to create tokens publicly
|
|
4
|
+
* shareable tokens while storing the token hash within the database.
|
|
5
|
+
*
|
|
6
|
+
* This class is used by the Auth and the Persona packages to manage
|
|
7
|
+
* tokens
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class VerificationToken {
|
|
10
|
+
/**
|
|
11
|
+
* Decodes a publicly shared token and return the series
|
|
12
|
+
* and the token value from it.
|
|
13
|
+
*
|
|
14
|
+
* Returns null when unable to decode the token because of
|
|
15
|
+
* invalid format or encoding.
|
|
16
|
+
*/
|
|
17
|
+
static decode(value: string): null | {
|
|
18
|
+
identifier: string;
|
|
19
|
+
secret: Secret<string>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Creates a transient token that can be shared with the persistence
|
|
23
|
+
* layer.
|
|
24
|
+
*/
|
|
25
|
+
static createTransientToken(userId: string | number | BigInt, size: number, expiresIn: string | number): {
|
|
26
|
+
secret: Secret<string>;
|
|
27
|
+
hash: string;
|
|
28
|
+
userId: string | number | BigInt;
|
|
29
|
+
expiresAt: Date;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Creates a secret opaque token and its hash.
|
|
33
|
+
*/
|
|
34
|
+
static seed(size: number): {
|
|
35
|
+
secret: Secret<string>;
|
|
36
|
+
hash: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Identifer is a unique sequence to identify the
|
|
40
|
+
* token within database. It should be the
|
|
41
|
+
* primary/unique key
|
|
42
|
+
*/
|
|
43
|
+
identifier: string | number | BigInt;
|
|
44
|
+
/**
|
|
45
|
+
* Reference to the user id for whom the token
|
|
46
|
+
* is generated.
|
|
47
|
+
*/
|
|
48
|
+
tokenableId: string | number | BigInt;
|
|
49
|
+
/**
|
|
50
|
+
* Hash is computed from the seed to later verify the validity
|
|
51
|
+
* of seed
|
|
52
|
+
*/
|
|
53
|
+
hash: string;
|
|
54
|
+
/**
|
|
55
|
+
* Timestamp at which the token will expire
|
|
56
|
+
*/
|
|
57
|
+
expiresAt: Date;
|
|
58
|
+
/**
|
|
59
|
+
* The value is a public representation of a token. It is created
|
|
60
|
+
* by combining the "identifier"."secret" via the "computeValue"
|
|
61
|
+
* method
|
|
62
|
+
*/
|
|
63
|
+
value?: Secret<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Compute the value property using the given secret. You can
|
|
66
|
+
* get secret via the static "createTransientToken" method.
|
|
67
|
+
*/
|
|
68
|
+
protected computeValue(secret: Secret<string>): void;
|
|
69
|
+
/**
|
|
70
|
+
* Check if the token has been expired. Verifies
|
|
71
|
+
* the "expiresAt" timestamp with the current
|
|
72
|
+
* date.
|
|
73
|
+
*/
|
|
74
|
+
isExpired(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Verifies the value of a token against the pre-defined hash
|
|
77
|
+
*/
|
|
78
|
+
verify(secret: Secret<string>): boolean;
|
|
79
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @adonisjs/core
|
|
3
|
+
*
|
|
4
|
+
* (c) AdonisJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
import string from '@poppinss/utils/string';
|
|
11
|
+
import { base64, safeEqual, Secret } from '@poppinss/utils';
|
|
12
|
+
/**
|
|
13
|
+
* Verification token class can be used to create tokens publicly
|
|
14
|
+
* shareable tokens while storing the token hash within the database.
|
|
15
|
+
*
|
|
16
|
+
* This class is used by the Auth and the Persona packages to manage
|
|
17
|
+
* tokens
|
|
18
|
+
*/
|
|
19
|
+
export class VerificationToken {
|
|
20
|
+
/**
|
|
21
|
+
* Decodes a publicly shared token and return the series
|
|
22
|
+
* and the token value from it.
|
|
23
|
+
*
|
|
24
|
+
* Returns null when unable to decode the token because of
|
|
25
|
+
* invalid format or encoding.
|
|
26
|
+
*/
|
|
27
|
+
static decode(value) {
|
|
28
|
+
/**
|
|
29
|
+
* Ensure value is a string and starts with the prefix.
|
|
30
|
+
*/
|
|
31
|
+
if (typeof value !== 'string') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Remove prefix from the rest of the token.
|
|
36
|
+
*/
|
|
37
|
+
if (!value) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const [identifier, ...tokenValue] = value.split('.');
|
|
41
|
+
if (!identifier || tokenValue.length === 0) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const decodedIdentifier = base64.urlDecode(identifier);
|
|
45
|
+
const decodedSecret = base64.urlDecode(tokenValue.join('.'));
|
|
46
|
+
if (!decodedIdentifier || !decodedSecret) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
identifier: decodedIdentifier,
|
|
51
|
+
secret: new Secret(decodedSecret),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a transient token that can be shared with the persistence
|
|
56
|
+
* layer.
|
|
57
|
+
*/
|
|
58
|
+
static createTransientToken(userId, size, expiresIn) {
|
|
59
|
+
const expiresAt = new Date();
|
|
60
|
+
expiresAt.setSeconds(expiresAt.getSeconds() + string.seconds.parse(expiresIn));
|
|
61
|
+
return {
|
|
62
|
+
userId,
|
|
63
|
+
expiresAt,
|
|
64
|
+
...this.seed(size),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates a secret opaque token and its hash.
|
|
69
|
+
*/
|
|
70
|
+
static seed(size) {
|
|
71
|
+
const seed = string.random(size);
|
|
72
|
+
const secret = new Secret(seed);
|
|
73
|
+
const hash = createHash('sha256').update(secret.release()).digest('hex');
|
|
74
|
+
return { secret, hash };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compute the value property using the given secret. You can
|
|
78
|
+
* get secret via the static "createTransientToken" method.
|
|
79
|
+
*/
|
|
80
|
+
computeValue(secret) {
|
|
81
|
+
this.value = new Secret(`${base64.urlEncode(String(this.identifier))}.${base64.urlEncode(secret.release())}`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if the token has been expired. Verifies
|
|
85
|
+
* the "expiresAt" timestamp with the current
|
|
86
|
+
* date.
|
|
87
|
+
*/
|
|
88
|
+
isExpired() {
|
|
89
|
+
return this.expiresAt < new Date();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Verifies the value of a token against the pre-defined hash
|
|
93
|
+
*/
|
|
94
|
+
verify(secret) {
|
|
95
|
+
const newHash = createHash('sha256').update(secret.release()).digest('hex');
|
|
96
|
+
return safeEqual(this.hash, newHash);
|
|
97
|
+
}
|
|
98
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/core",
|
|
3
3
|
"description": "Core of AdonisJS",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.17.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.6.0"
|
|
7
7
|
},
|
|
@@ -94,8 +94,8 @@
|
|
|
94
94
|
"@japa/runner": "^3.1.4",
|
|
95
95
|
"@japa/snapshot": "^2.0.6",
|
|
96
96
|
"@release-it/conventional-changelog": "^9.0.3",
|
|
97
|
-
"@swc/core": "1.
|
|
98
|
-
"@types/node": "^22.10.
|
|
97
|
+
"@swc/core": "1.10.1",
|
|
98
|
+
"@types/node": "^22.10.2",
|
|
99
99
|
"@types/pretty-hrtime": "^1.0.3",
|
|
100
100
|
"@types/sinon": "^17.0.3",
|
|
101
101
|
"@types/supertest": "^6.0.2",
|
|
@@ -103,21 +103,22 @@
|
|
|
103
103
|
"@vinejs/vine": "^3.0.0",
|
|
104
104
|
"argon2": "^0.41.1",
|
|
105
105
|
"bcrypt": "^5.1.1",
|
|
106
|
-
"c8": "^10.1.
|
|
106
|
+
"c8": "^10.1.3",
|
|
107
107
|
"copyfiles": "^2.4.1",
|
|
108
108
|
"cross-env": "^7.0.3",
|
|
109
109
|
"del-cli": "^6.0.0",
|
|
110
110
|
"edge.js": "^6.2.0",
|
|
111
|
-
"eslint": "^9.
|
|
112
|
-
"execa": "^9.5.
|
|
111
|
+
"eslint": "^9.17.0",
|
|
112
|
+
"execa": "^9.5.2",
|
|
113
113
|
"get-port": "^7.1.0",
|
|
114
114
|
"github-label-sync": "^2.3.1",
|
|
115
115
|
"husky": "^9.1.7",
|
|
116
|
-
"prettier": "^3.4.
|
|
116
|
+
"prettier": "^3.4.2",
|
|
117
117
|
"release-it": "^17.10.0",
|
|
118
118
|
"sinon": "^19.0.2",
|
|
119
119
|
"supertest": "^7.0.0",
|
|
120
120
|
"test-console": "^2.0.0",
|
|
121
|
+
"timekeeper": "^2.3.1",
|
|
121
122
|
"ts-node-maintained": "^10.9.4",
|
|
122
123
|
"typescript": "^5.7.2"
|
|
123
124
|
},
|
|
@@ -132,7 +133,7 @@
|
|
|
132
133
|
"@adonisjs/fold": "^10.1.3",
|
|
133
134
|
"@adonisjs/hash": "^9.0.5",
|
|
134
135
|
"@adonisjs/health": "^2.0.0",
|
|
135
|
-
"@adonisjs/http-server": "^7.
|
|
136
|
+
"@adonisjs/http-server": "^7.4.0",
|
|
136
137
|
"@adonisjs/logger": "^6.0.5",
|
|
137
138
|
"@adonisjs/repl": "^4.0.1",
|
|
138
139
|
"@antfu/install-pkg": "^0.5.0",
|