@adonisjs/core 6.15.1 → 6.16.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.
@@ -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
  /**
@@ -1,8 +1,9 @@
1
- import { BaseLiteralType } from '@vinejs/vine';
1
+ import { symbols, BaseLiteralType } from '@vinejs/vine';
2
2
  import type { Validation, FieldContext, FieldOptions } from '@vinejs/vine/types';
3
3
  import type { MultipartFile, FileValidationOptions } from '@adonisjs/bodyparser/types';
4
4
  import type { ApplicationService } from '../src/types.js';
5
5
  import { RequestValidator } from '../modules/http/main.js';
6
+ declare const MULTIPART_FILE: typeof symbols.SUBTYPE;
6
7
  /**
7
8
  * Validation options accepted by the "file" rule
8
9
  */
@@ -28,6 +29,7 @@ declare module '@adonisjs/core/http' {
28
29
  */
29
30
  declare class VineMultipartFile extends BaseLiteralType<MultipartFile, MultipartFile, MultipartFile> {
30
31
  #private;
32
+ [MULTIPART_FILE]: string;
31
33
  constructor(validationOptions?: FileRuleValidationOptions, options?: FieldOptions, validations?: Validation<any>[]);
32
34
  clone(): this;
33
35
  }
@@ -6,8 +6,9 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import vine, { BaseLiteralType, Vine } from '@vinejs/vine';
9
+ import vine, { symbols, BaseLiteralType, Vine } from '@vinejs/vine';
10
10
  import { Request, RequestValidator } from '../modules/http/main.js';
11
+ const MULTIPART_FILE = symbols.SUBTYPE ?? Symbol.for('subtype');
11
12
  /**
12
13
  * Checks if the value is an instance of multipart file
13
14
  * from bodyparser.
@@ -60,6 +61,7 @@ const isMultipartFile = vine.createRule((file, options, field) => {
60
61
  */
61
62
  class VineMultipartFile extends BaseLiteralType {
62
63
  #validationOptions;
64
+ [MULTIPART_FILE] = 'multipartFile';
63
65
  constructor(validationOptions, options, validations) {
64
66
  super(options, validations || [isMultipartFile(validationOptions || {})]);
65
67
  this.#validationOptions = validationOptions;
@@ -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.15.1",
4
+ "version": "6.16.0",
5
5
  "engines": {
6
6
  "node": ">=20.6.0"
7
7
  },
@@ -94,13 +94,13 @@
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.9.3",
97
+ "@swc/core": "1.10.0",
98
98
  "@types/node": "^22.10.1",
99
99
  "@types/pretty-hrtime": "^1.0.3",
100
100
  "@types/sinon": "^17.0.3",
101
101
  "@types/supertest": "^6.0.2",
102
102
  "@types/test-console": "^2.0.3",
103
- "@vinejs/vine": "^2.1.0",
103
+ "@vinejs/vine": "^3.0.0",
104
104
  "argon2": "^0.41.1",
105
105
  "bcrypt": "^5.1.1",
106
106
  "c8": "^10.1.2",
@@ -108,16 +108,17 @@
108
108
  "cross-env": "^7.0.3",
109
109
  "del-cli": "^6.0.0",
110
110
  "edge.js": "^6.2.0",
111
- "eslint": "^9.15.0",
111
+ "eslint": "^9.16.0",
112
112
  "execa": "^9.5.1",
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.1",
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
  },
@@ -153,7 +154,7 @@
153
154
  },
154
155
  "peerDependencies": {
155
156
  "@adonisjs/assembler": "^7.8.0",
156
- "@vinejs/vine": "^2.1.0",
157
+ "@vinejs/vine": "^2.1.0 || ^3.0.0",
157
158
  "argon2": "^0.31.2 || ^0.41.0",
158
159
  "bcrypt": "^5.1.1",
159
160
  "edge.js": "^6.2.0"