@webda/core 4.0.0-beta.6 → 4.0.0-beta.8

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.
Files changed (143) hide show
  1. package/README.md +6 -5
  2. package/lib/application/application.d.ts +18 -0
  3. package/lib/application/application.d.ts.map +1 -1
  4. package/lib/application/application.js +49 -11
  5. package/lib/application/application.js.map +1 -1
  6. package/lib/application/iconfiguration.d.ts +31 -0
  7. package/lib/application/iconfiguration.d.ts.map +1 -1
  8. package/lib/application/iconfiguration.js.map +1 -1
  9. package/lib/application/unpackedapplication.d.ts.map +1 -1
  10. package/lib/application/unpackedapplication.js +7 -5
  11. package/lib/application/unpackedapplication.js.map +1 -1
  12. package/lib/bin/cli-phase.d.ts +18 -2
  13. package/lib/bin/cli-phase.d.ts.map +1 -1
  14. package/lib/bin/cli-phase.js +25 -0
  15. package/lib/bin/cli-phase.js.map +1 -1
  16. package/lib/bin/cli.d.ts +8 -0
  17. package/lib/bin/cli.d.ts.map +1 -1
  18. package/lib/bin/cli.js +94 -35
  19. package/lib/bin/cli.js.map +1 -1
  20. package/lib/configurations/configuration.service.d.ts +7 -0
  21. package/lib/configurations/configuration.service.d.ts.map +1 -1
  22. package/lib/configurations/configuration.service.js +18 -5
  23. package/lib/configurations/configuration.service.js.map +1 -1
  24. package/lib/configurations/kubernetesconfiguration.service.d.ts.map +1 -1
  25. package/lib/configurations/kubernetesconfiguration.service.js +1 -4
  26. package/lib/configurations/kubernetesconfiguration.service.js.map +1 -1
  27. package/lib/contexts/httpcontext.d.ts +15 -1
  28. package/lib/contexts/httpcontext.d.ts.map +1 -1
  29. package/lib/contexts/httpcontext.js +61 -19
  30. package/lib/contexts/httpcontext.js.map +1 -1
  31. package/lib/contexts/operationcontext.d.ts +6 -0
  32. package/lib/contexts/operationcontext.d.ts.map +1 -1
  33. package/lib/contexts/operationcontext.js +16 -2
  34. package/lib/contexts/operationcontext.js.map +1 -1
  35. package/lib/contexts/restcontext.d.ts +110 -0
  36. package/lib/contexts/restcontext.d.ts.map +1 -0
  37. package/lib/contexts/restcontext.js +247 -0
  38. package/lib/contexts/restcontext.js.map +1 -0
  39. package/lib/contexts/streamingcontext.d.ts +71 -0
  40. package/lib/contexts/streamingcontext.d.ts.map +1 -0
  41. package/lib/contexts/streamingcontext.js +93 -0
  42. package/lib/contexts/streamingcontext.js.map +1 -0
  43. package/lib/contexts/webcontext.d.ts +20 -0
  44. package/lib/contexts/webcontext.d.ts.map +1 -1
  45. package/lib/contexts/webcontext.js +43 -10
  46. package/lib/contexts/webcontext.js.map +1 -1
  47. package/lib/contexts/websocketcontext.d.ts +39 -0
  48. package/lib/contexts/websocketcontext.d.ts.map +1 -0
  49. package/lib/contexts/websocketcontext.js +67 -0
  50. package/lib/contexts/websocketcontext.js.map +1 -0
  51. package/lib/core/asyncqueue.d.ts +50 -0
  52. package/lib/core/asyncqueue.d.ts.map +1 -0
  53. package/lib/core/asyncqueue.js +96 -0
  54. package/lib/core/asyncqueue.js.map +1 -0
  55. package/lib/core/core.d.ts +18 -0
  56. package/lib/core/core.d.ts.map +1 -1
  57. package/lib/core/core.js +72 -7
  58. package/lib/core/core.js.map +1 -1
  59. package/lib/core/icore.d.ts +14 -1
  60. package/lib/core/icore.d.ts.map +1 -1
  61. package/lib/core/icore.js.map +1 -1
  62. package/lib/core/instancestorage.d.ts +1 -0
  63. package/lib/core/instancestorage.d.ts.map +1 -1
  64. package/lib/core/instancestorage.js +1 -0
  65. package/lib/core/instancestorage.js.map +1 -1
  66. package/lib/core/operations.d.ts +49 -6
  67. package/lib/core/operations.d.ts.map +1 -1
  68. package/lib/core/operations.js +187 -24
  69. package/lib/core/operations.js.map +1 -1
  70. package/lib/deployers/git.d.ts +4 -2
  71. package/lib/deployers/git.d.ts.map +1 -1
  72. package/lib/deployers/git.js +44 -5
  73. package/lib/deployers/git.js.map +1 -1
  74. package/lib/errors/errors.d.ts +15 -0
  75. package/lib/errors/errors.d.ts.map +1 -1
  76. package/lib/errors/errors.js +20 -0
  77. package/lib/errors/errors.js.map +1 -1
  78. package/lib/index.d.ts +5 -0
  79. package/lib/index.d.ts.map +1 -1
  80. package/lib/index.js +5 -0
  81. package/lib/index.js.map +1 -1
  82. package/lib/rest/restoperationstransport.service.d.ts +108 -0
  83. package/lib/rest/restoperationstransport.service.d.ts.map +1 -1
  84. package/lib/rest/restoperationstransport.service.js +360 -10
  85. package/lib/rest/restoperationstransport.service.js.map +1 -1
  86. package/lib/rest/router.service.d.ts +1 -1
  87. package/lib/rest/router.service.d.ts.map +1 -1
  88. package/lib/rest/router.service.js +5 -2
  89. package/lib/rest/router.service.js.map +1 -1
  90. package/lib/services/authenticatedencryption.d.ts +25 -0
  91. package/lib/services/authenticatedencryption.d.ts.map +1 -0
  92. package/lib/services/authenticatedencryption.js +56 -0
  93. package/lib/services/authenticatedencryption.js.map +1 -0
  94. package/lib/services/binary.service.d.ts +1 -1
  95. package/lib/services/binary.service.d.ts.map +1 -1
  96. package/lib/services/binary.service.js.map +1 -1
  97. package/lib/services/cloudbinary.d.ts.map +1 -1
  98. package/lib/services/cloudbinary.js +3 -2
  99. package/lib/services/cloudbinary.js.map +1 -1
  100. package/lib/services/command.d.ts +7 -1
  101. package/lib/services/command.d.ts.map +1 -1
  102. package/lib/services/command.js +4 -0
  103. package/lib/services/command.js.map +1 -1
  104. package/lib/services/cryptoservice.service.d.ts +405 -25
  105. package/lib/services/cryptoservice.service.d.ts.map +1 -1
  106. package/lib/services/cryptoservice.service.js +779 -72
  107. package/lib/services/cryptoservice.service.js.map +1 -1
  108. package/lib/services/httpserver.service.d.ts.map +1 -1
  109. package/lib/services/httpserver.service.js +20 -9
  110. package/lib/services/httpserver.service.js.map +1 -1
  111. package/lib/services/icryptoservice.d.ts +11 -0
  112. package/lib/services/icryptoservice.d.ts.map +1 -1
  113. package/lib/services/icryptoservice.js +2 -0
  114. package/lib/services/icryptoservice.js.map +1 -1
  115. package/lib/services/mailer.service.d.ts +4 -0
  116. package/lib/services/mailer.service.d.ts.map +1 -1
  117. package/lib/services/mailer.service.js +7 -1
  118. package/lib/services/mailer.service.js.map +1 -1
  119. package/lib/services/operationstransport.d.ts +13 -0
  120. package/lib/services/operationstransport.d.ts.map +1 -1
  121. package/lib/services/operationstransport.js +28 -6
  122. package/lib/services/operationstransport.js.map +1 -1
  123. package/lib/services/pki.encrypter.d.ts +214 -0
  124. package/lib/services/pki.encrypter.d.ts.map +1 -0
  125. package/lib/services/pki.encrypter.js +350 -0
  126. package/lib/services/pki.encrypter.js.map +1 -0
  127. package/lib/services/secretscheck.d.ts +120 -0
  128. package/lib/services/secretscheck.d.ts.map +1 -0
  129. package/lib/services/secretscheck.js +322 -0
  130. package/lib/services/secretscheck.js.map +1 -0
  131. package/lib/services/servicecommands.d.ts +8 -4
  132. package/lib/services/servicecommands.d.ts.map +1 -1
  133. package/lib/services/servicecommands.js +14 -5
  134. package/lib/services/servicecommands.js.map +1 -1
  135. package/lib/session/manager.model.d.ts +3 -1
  136. package/lib/session/manager.model.d.ts.map +1 -1
  137. package/lib/session/manager.model.js +6 -3
  138. package/lib/session/manager.model.js.map +1 -1
  139. package/lib/test/objects.d.ts.map +1 -1
  140. package/lib/test/objects.js +3 -1
  141. package/lib/test/objects.js.map +1 -1
  142. package/package.json +12 -11
  143. package/webda.module.json +135 -41
@@ -0,0 +1,120 @@
1
+ import type { JSONSchema7 } from "json-schema";
2
+ import { type DeploymentUnit } from "../application/deployment.js";
3
+ /**
4
+ * JSON Schema keyword marking a configuration value that must be encrypted
5
+ *
6
+ * Written by the compiler for a property typed with `SecretString` or tagged `@secret`:
7
+ * - `true`: the whole value, every string below it
8
+ * - a list of names: only these children of the object, a name can be a dotted path
9
+ * and the arrays on the way are traversed (`users.token`)
10
+ */
11
+ export declare const SECRET_KEYWORD = "x-webda-secret";
12
+ /**
13
+ * Encrypter of the values kept in clear text on purpose: `crypt:none:<value>`
14
+ */
15
+ export declare const OPT_OUT_ENCRYPTER = "none";
16
+ /**
17
+ * A secret configuration value that is not encrypted
18
+ *
19
+ * It never holds the value itself.
20
+ */
21
+ export interface SecretFinding {
22
+ /**
23
+ * Configuration path of the value, like `services.db.postgresqlServer.password`
24
+ */
25
+ path: string;
26
+ /**
27
+ * Location of the value in the checked configuration object, like `["units", 0, "apiKey"]`
28
+ */
29
+ location?: (string | number)[];
30
+ /**
31
+ * Service or deployment unit name
32
+ */
33
+ service?: string;
34
+ /**
35
+ * Service type
36
+ */
37
+ type?: string;
38
+ /**
39
+ * - `plain`: written in clear text
40
+ * - `marked`: still `encrypt:` or `sencrypt:`, run `webda config encrypt`
41
+ * - `opted-out`: kept in clear text on purpose with `crypt:none:` or `scrypt:none:`
42
+ */
43
+ reason: "plain" | "marked" | "opted-out";
44
+ }
45
+ /**
46
+ * Format a configuration path: `services.db.keys[0]`
47
+ * @param path - the path segments
48
+ * @returns the formatted path
49
+ */
50
+ export declare function formatSecretPath(path: (string | number)[]): string;
51
+ /**
52
+ * Find the secrets of a value that are not encrypted
53
+ *
54
+ * A schema node marked {@link SECRET_KEYWORD} must hold a `crypt:` or `scrypt:` string, or nothing.
55
+ * The findings never contain the values.
56
+ *
57
+ * @param value - the value, a service configuration for example
58
+ * @param schema - its schema
59
+ * @param root - the document holding the definitions, for `$ref`
60
+ * @param path - path of the value, prefixed to the findings
61
+ * @returns the findings
62
+ */
63
+ export declare function findUnencryptedSecrets(value: any, schema: JSONSchema7, root?: JSONSchema7, path?: (string | number)[]): SecretFinding[];
64
+ /**
65
+ * Parse the patterns of the secret paths to exclude
66
+ *
67
+ * A pattern uses the path syntax of the findings, `$.` prefix optional: `*` matches one name or index
68
+ * (`units[*].auth.pass`), `**` matches anything, and a pattern also excludes the values below it
69
+ * (`services.demo`).
70
+ *
71
+ * @param patterns - the patterns, a comma-separated string or a list
72
+ * @returns a function telling whether a finding path is excluded
73
+ */
74
+ export declare function secretPathExcluder(patterns?: string | string[]): (path: string) => boolean;
75
+ /**
76
+ * Configuration to check: an application configuration, a deployment, or both merged
77
+ */
78
+ export interface SecretsCheckConfiguration {
79
+ /**
80
+ * Services configuration
81
+ */
82
+ services?: Record<string, any>;
83
+ /**
84
+ * Global parameters, merged into every service
85
+ */
86
+ parameters?: Record<string, any>;
87
+ /**
88
+ * Parameters shared by the deployment units
89
+ */
90
+ resources?: Record<string, any>;
91
+ /**
92
+ * Deployment units
93
+ */
94
+ units?: DeploymentUnit[];
95
+ }
96
+ /**
97
+ * Find the unencrypted secrets of a configuration
98
+ *
99
+ * Each service is checked against the schema of its type, with the global parameters it inherits:
100
+ * a secret written in `parameters` is reported once, under `parameters`. The deployment units are
101
+ * checked with the `resources` they inherit, reported under `resources`.
102
+ *
103
+ * @param configuration - the configuration to check
104
+ * @param options - how to find the schemas
105
+ * @param options.getSchema - the schema of a service type
106
+ * @param options.completeNamespace - add the namespace to a service type
107
+ * @param options.getType - the type of a service without one, from the application configuration
108
+ * @param options.inheritingServices - other services inheriting `parameters`, defined in another file
109
+ * @returns the findings, and the service types without schema
110
+ */
111
+ export declare function findConfigurationSecrets(configuration: SecretsCheckConfiguration, options: {
112
+ getSchema: (type: string) => JSONSchema7 | undefined;
113
+ completeNamespace?: (type: string) => string;
114
+ getType?: (service: string) => string | undefined;
115
+ inheritingServices?: Record<string, any>;
116
+ }): {
117
+ findings: SecretFinding[];
118
+ unknownTypes: string[];
119
+ };
120
+ //# sourceMappingURL=secretscheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secretscheck.d.ts","sourceRoot":"","sources":["../../src/services/secretscheck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9F;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,iBAAiB,SAAS,CAAC;AAExC;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC/B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;CAC1C;AA4BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAOlE;AAqKD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,WAAoB,EAC1B,IAAI,GAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,GAC7B,aAAa,EAAE,CAEjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,MAAM,GAAG,MAAM,EAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAmB9F;AAmBD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,yBAAyB,EACxC,OAAO,EAAE;IACP,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IACrD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC1C,GACA;IAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CA6DvD"}
@@ -0,0 +1,322 @@
1
+ import { getDeploymentUnitServices } from "../application/deployment.js";
2
+ /**
3
+ * JSON Schema keyword marking a configuration value that must be encrypted
4
+ *
5
+ * Written by the compiler for a property typed with `SecretString` or tagged `@secret`:
6
+ * - `true`: the whole value, every string below it
7
+ * - a list of names: only these children of the object, a name can be a dotted path
8
+ * and the arrays on the way are traversed (`users.token`)
9
+ */
10
+ export const SECRET_KEYWORD = "x-webda-secret";
11
+ /**
12
+ * Encrypter of the values kept in clear text on purpose: `crypt:none:<value>`
13
+ */
14
+ export const OPT_OUT_ENCRYPTER = "none";
15
+ /**
16
+ * Limit of `$ref` followed without going down the value, protects from a reference cycle
17
+ */
18
+ const MAX_REF_DEPTH = 32;
19
+ /**
20
+ * Check if a value is a plain object, class instances are not
21
+ * @param value - the value to test
22
+ * @returns true for a plain object
23
+ */
24
+ function isPlainObject(value) {
25
+ if (value === null || typeof value !== "object") {
26
+ return false;
27
+ }
28
+ const proto = Object.getPrototypeOf(value);
29
+ return proto === Object.prototype || proto === null;
30
+ }
31
+ /**
32
+ * Format a configuration path: `services.db.keys[0]`
33
+ * @param path - the path segments
34
+ * @returns the formatted path
35
+ */
36
+ export function formatSecretPath(path) {
37
+ return path.reduce((res, segment) => {
38
+ if (typeof segment === "number") {
39
+ return `${res}[${segment}]`;
40
+ }
41
+ return res ? `${res}.${segment}` : segment;
42
+ }, "");
43
+ }
44
+ /**
45
+ * Classify a secret value
46
+ *
47
+ * `crypt:` and `scrypt:` values are encrypted, except the opted-out `crypt:none:` ones. Unset values (`""`,
48
+ * `null`, `undefined`) are allowed: the service then falls back to its environment.
49
+ *
50
+ * @param value - the secret value
51
+ * @returns the reason it fails, or undefined when it is fine
52
+ */
53
+ function classify(value) {
54
+ if (typeof value !== "string" || value === "") {
55
+ return undefined;
56
+ }
57
+ if (value.startsWith(`crypt:${OPT_OUT_ENCRYPTER}:`) || value.startsWith(`scrypt:${OPT_OUT_ENCRYPTER}:`)) {
58
+ return "opted-out";
59
+ }
60
+ if (/^s?crypt:/.test(value)) {
61
+ return undefined;
62
+ }
63
+ return /^s?encrypt:/.test(value) ? "marked" : "plain";
64
+ }
65
+ /**
66
+ * Check a secret value: a string, or every string below an object or an array
67
+ * @param value - the secret value
68
+ * @param path - its path
69
+ * @param findings - collected findings
70
+ */
71
+ function checkLeaves(value, path, findings) {
72
+ if (Array.isArray(value)) {
73
+ value.forEach((item, index) => checkLeaves(item, [...path, index], findings));
74
+ return;
75
+ }
76
+ if (isPlainObject(value)) {
77
+ for (const [key, item] of Object.entries(value)) {
78
+ checkLeaves(item, [...path, key], findings);
79
+ }
80
+ return;
81
+ }
82
+ const reason = classify(value);
83
+ if (reason) {
84
+ findings.push({ path, reason });
85
+ }
86
+ }
87
+ /**
88
+ * Check the children of a value listed by a scoped secret marker
89
+ * @param value - the value holding the children
90
+ * @param segments - the remaining segments of the child name
91
+ * @param path - path of the value
92
+ * @param findings - collected findings
93
+ */
94
+ function checkScoped(value, segments, path, findings) {
95
+ if (Array.isArray(value)) {
96
+ value.forEach((item, index) => checkScoped(item, segments, [...path, index], findings));
97
+ return;
98
+ }
99
+ if (segments.length === 0) {
100
+ checkLeaves(value, path, findings);
101
+ return;
102
+ }
103
+ // A string where an object is expected (a file path for example) holds no listed child
104
+ if (isPlainObject(value) && value[segments[0]] !== undefined) {
105
+ checkScoped(value[segments[0]], segments.slice(1), [...path, segments[0]], findings);
106
+ }
107
+ }
108
+ /**
109
+ * Resolve a `#/definitions/...` reference
110
+ * @param ref - the reference
111
+ * @param root - the document holding the definitions
112
+ * @returns the referenced schema
113
+ */
114
+ function resolveRef(ref, root) {
115
+ if (!ref.startsWith("#/")) {
116
+ return undefined;
117
+ }
118
+ let target = root;
119
+ for (const segment of ref.substring(2).split("/")) {
120
+ target = target?.[decodeURIComponent(segment).replace(/~1/g, "/").replace(/~0/g, "~")];
121
+ }
122
+ return typeof target === "object" ? target : undefined;
123
+ }
124
+ /**
125
+ * Walk a value with its schema and collect the secrets that are not encrypted
126
+ * @param value - the value
127
+ * @param schema - its schema
128
+ * @param root - the document, for `$ref`
129
+ * @param path - path of the value
130
+ * @param findings - collected findings
131
+ * @param refDepth - `$ref` followed since the value last changed
132
+ */
133
+ function walk(value, schema, root, path, findings, refDepth = 0) {
134
+ if (value === undefined || value === null || !schema || typeof schema !== "object") {
135
+ return;
136
+ }
137
+ const marker = schema[SECRET_KEYWORD];
138
+ if (marker === true) {
139
+ checkLeaves(value, path, findings);
140
+ return;
141
+ }
142
+ if (Array.isArray(marker)) {
143
+ for (const name of marker) {
144
+ checkScoped(value, String(name).split("."), path, findings);
145
+ }
146
+ }
147
+ if (schema.$ref && refDepth < MAX_REF_DEPTH) {
148
+ walk(value, resolveRef(schema.$ref, root), root, path, findings, refDepth + 1);
149
+ }
150
+ for (const branch of [...(schema.anyOf ?? []), ...(schema.oneOf ?? []), ...(schema.allOf ?? [])]) {
151
+ walk(value, branch, root, path, findings, refDepth + 1);
152
+ }
153
+ if (Array.isArray(value)) {
154
+ value.forEach((item, index) => {
155
+ const items = Array.isArray(schema.items) ? schema.items[index] : schema.items;
156
+ walk(item, items, root, [...path, index], findings);
157
+ });
158
+ return;
159
+ }
160
+ if (isPlainObject(value)) {
161
+ for (const [key, item] of Object.entries(value)) {
162
+ const child = schema.properties?.[key] ?? schema.additionalProperties;
163
+ walk(item, child, root, [...path, key], findings);
164
+ }
165
+ }
166
+ }
167
+ /**
168
+ * Collect the secrets of a value that are not encrypted, with their path in segments
169
+ * @param value - the value
170
+ * @param schema - its schema
171
+ * @param root - the document, for `$ref`
172
+ * @param path - path of the value
173
+ * @returns the findings, each path once
174
+ */
175
+ function collect(value, schema, root = schema, path = []) {
176
+ const findings = [];
177
+ walk(value, schema, root, path, findings);
178
+ // A value can be reached through several branches or markers
179
+ const seen = new Set();
180
+ return findings.filter(finding => {
181
+ const key = JSON.stringify(finding.path);
182
+ if (seen.has(key)) {
183
+ return false;
184
+ }
185
+ seen.add(key);
186
+ return true;
187
+ });
188
+ }
189
+ /**
190
+ * Find the secrets of a value that are not encrypted
191
+ *
192
+ * A schema node marked {@link SECRET_KEYWORD} must hold a `crypt:` or `scrypt:` string, or nothing.
193
+ * The findings never contain the values.
194
+ *
195
+ * @param value - the value, a service configuration for example
196
+ * @param schema - its schema
197
+ * @param root - the document holding the definitions, for `$ref`
198
+ * @param path - path of the value, prefixed to the findings
199
+ * @returns the findings
200
+ */
201
+ export function findUnencryptedSecrets(value, schema, root = schema, path = []) {
202
+ return collect(value, schema, root, path).map(({ path, reason }) => ({ path: formatSecretPath(path), reason }));
203
+ }
204
+ /**
205
+ * Parse the patterns of the secret paths to exclude
206
+ *
207
+ * A pattern uses the path syntax of the findings, `$.` prefix optional: `*` matches one name or index
208
+ * (`units[*].auth.pass`), `**` matches anything, and a pattern also excludes the values below it
209
+ * (`services.demo`).
210
+ *
211
+ * @param patterns - the patterns, a comma-separated string or a list
212
+ * @returns a function telling whether a finding path is excluded
213
+ */
214
+ export function secretPathExcluder(patterns = []) {
215
+ const list = (typeof patterns === "string" ? patterns.split(",") : patterns)
216
+ .map(pattern => pattern.trim().replace(/^\$\.?/, ""))
217
+ .filter(pattern => pattern !== "");
218
+ const expressions = list.map(pattern => {
219
+ let source = "";
220
+ for (let i = 0; i < pattern.length; i++) {
221
+ if (pattern.startsWith("**", i)) {
222
+ source += ".*";
223
+ i++;
224
+ }
225
+ else if (pattern[i] === "*") {
226
+ source += "[^.\\[\\]]+";
227
+ }
228
+ else {
229
+ source += pattern[i].replace(/[.+?^${}()|[\]\\]/g, "\\$&");
230
+ }
231
+ }
232
+ return new RegExp(`^${source}(?:[.[].*)?$`);
233
+ });
234
+ return path => expressions.some(expression => expression.test(path));
235
+ }
236
+ /**
237
+ * Check if a structure holds a value at a path
238
+ * @param data - the structure
239
+ * @param path - the path
240
+ * @returns true when the value is defined
241
+ */
242
+ function hasPath(data, path) {
243
+ let target = data;
244
+ for (const segment of path) {
245
+ if (target === null || typeof target !== "object" || target[segment] === undefined) {
246
+ return false;
247
+ }
248
+ target = target[segment];
249
+ }
250
+ return true;
251
+ }
252
+ /**
253
+ * Find the unencrypted secrets of a configuration
254
+ *
255
+ * Each service is checked against the schema of its type, with the global parameters it inherits:
256
+ * a secret written in `parameters` is reported once, under `parameters`. The deployment units are
257
+ * checked with the `resources` they inherit, reported under `resources`.
258
+ *
259
+ * @param configuration - the configuration to check
260
+ * @param options - how to find the schemas
261
+ * @param options.getSchema - the schema of a service type
262
+ * @param options.completeNamespace - add the namespace to a service type
263
+ * @param options.getType - the type of a service without one, from the application configuration
264
+ * @param options.inheritingServices - other services inheriting `parameters`, defined in another file
265
+ * @returns the findings, and the service types without schema
266
+ */
267
+ export function findConfigurationSecrets(configuration, options) {
268
+ const completeNamespace = options.completeNamespace ?? (type => type);
269
+ const findings = [];
270
+ const unknownTypes = new Set();
271
+ const reported = new Set();
272
+ const report = (finding) => {
273
+ if (reported.has(finding.path))
274
+ return;
275
+ reported.add(finding.path);
276
+ findings.push(finding);
277
+ };
278
+ const check = (name, type, own, merged, ownLocation, ownPrefix, inheritedPrefix) => {
279
+ const schema = options.getSchema(type);
280
+ if (!schema) {
281
+ unknownTypes.add(type);
282
+ return;
283
+ }
284
+ for (const { path, reason } of collect(merged, schema)) {
285
+ const inherited = !hasPath(own, path);
286
+ report({
287
+ path: formatSecretPath([...(inherited ? [inheritedPrefix] : ownPrefix), ...path]),
288
+ location: [...(inherited ? [inheritedPrefix] : ownLocation), ...path],
289
+ service: name,
290
+ type,
291
+ reason
292
+ });
293
+ }
294
+ };
295
+ const parameters = configuration.parameters ?? {};
296
+ const services = configuration.services ?? {};
297
+ for (const [name, service] of Object.entries(services)) {
298
+ if (!isPlainObject(service))
299
+ continue;
300
+ const type = completeNamespace(service.type ?? options.getType?.(name) ?? name);
301
+ check(name, type, service, { ...parameters, ...service }, ["services", name], ["services", name], "parameters");
302
+ }
303
+ // The parameters also reach the services of the other files, unless they set the same key
304
+ for (const [name, service] of Object.entries(options.inheritingServices ?? {})) {
305
+ if (!isPlainObject(service) || services[name] !== undefined)
306
+ continue;
307
+ const type = completeNamespace(service.type ?? name);
308
+ const inherited = Object.fromEntries(Object.entries(parameters).filter(([key]) => service[key] === undefined));
309
+ check(name, type, {}, inherited, ["services", name], ["services", name], "parameters");
310
+ }
311
+ const units = configuration.units ?? [];
312
+ if (units.length) {
313
+ const merged = getDeploymentUnitServices({ units, resources: configuration.resources }, completeNamespace);
314
+ units.forEach((unit, index) => {
315
+ const { name, type: _type, ...own } = unit;
316
+ const { type, ...service } = merged[name];
317
+ check(name, type, own, service, ["units", index], [`units[${name}]`], "resources");
318
+ });
319
+ }
320
+ return { findings, unknownTypes: [...unknownTypes] };
321
+ }
322
+ //# sourceMappingURL=secretscheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secretscheck.js","sourceRoot":"","sources":["../../src/services/secretscheck.ts"],"names":[],"mappings":"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"}
@@ -29,14 +29,16 @@ export interface ServiceCommandInfo {
29
29
  /**
30
30
  * Lifecycle phase declared by each service providing this command, in the
31
31
  * same order as `services`. Values are one of:
32
+ * - `"application"`: service declared phase "application", a static method called without Core.
32
33
  * - `"resolved"`: service declared phase "resolved" (e.g. via `@BuildCommand`).
33
34
  * - `"initialized"`: service declared phase "initialized".
34
35
  * - `undefined`: service did not declare a phase (treat as "initialized").
35
36
  *
36
37
  * The CLI dispatcher uses this to decide whether to skip `Core.init()`:
37
- * all-"resolved" → resolve-only; all-"initialized"/undefined → full init; mixed → error.
38
+ * all-"application" → no Core; all-"resolved" → resolve-only; all-"initialized"/undefined → full init;
39
+ * mixed → error.
38
40
  */
39
- phases: Array<"resolved" | "initialized" | undefined>;
41
+ phases: Array<"application" | "resolved" | "initialized" | undefined>;
40
42
  }
41
43
  /**
42
44
  * Collect all CLI commands declared by services across all loaded modules.
@@ -73,14 +75,16 @@ export declare function collectServiceCommands(app: Application): {
73
75
  * (supports suffix matching).
74
76
  *
75
77
  * Each service's command handler is called with the parsed arguments as
76
- * positional parameters.
78
+ * positional parameters. A handler returning a number sets the exit code: the
79
+ * highest one wins, any other result counts as `0`.
77
80
  *
78
81
  * @param cmdName - The command name to execute (e.g., `"serve"`, `"migrate"`)
79
82
  * @param cmdInfo - The merged command definition from {@link collectServiceCommands}
80
83
  * @param args - Parsed argument values keyed by argument name
81
84
  * @param services - Map of service name to service instance (from Core.getServices())
82
85
  * @param serviceFilter - Optional list of service names to filter to (supports suffix matching)
83
- * @returns `0` on success, `1` if no services match the filter, a method is missing or no service instance ran
86
+ * @returns the highest exit code returned by the handlers (`0` on success), `1` if no services match the filter,
87
+ * a method is missing or no service instance ran
84
88
  *
85
89
  * @example
86
90
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"servicecommands.d.ts","sourceRoot":"","sources":["../../src/services/servicecommands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAqB,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,oDAAoD;IACpD,IAAI,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAA;KAAE,CAAC;IAC/C,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;;;OASG;IACH,MAAM,EAAE,KAAK,CAAC,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,WAAW,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CAAE,CAoC/F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAC5B,QAAQ,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,EAC5C,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,MAAM,CAAC,CA8EjB"}
1
+ {"version":3,"file":"servicecommands.d.ts","sourceRoot":"","sources":["../../src/services/servicecommands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAqB,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,oDAAoD;IACpD,IAAI,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAA;KAAE,CAAC;IAC/C,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,KAAK,CAAC,aAAa,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC,CAAC;CACvE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,WAAW,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CAAE,CAoC/F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAC5B,QAAQ,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAA;CAAE,EAC5C,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,MAAM,CAAC,CAsFjB"}
@@ -67,14 +67,16 @@ export function collectServiceCommands(app) {
67
67
  * (supports suffix matching).
68
68
  *
69
69
  * Each service's command handler is called with the parsed arguments as
70
- * positional parameters.
70
+ * positional parameters. A handler returning a number sets the exit code: the
71
+ * highest one wins, any other result counts as `0`.
71
72
  *
72
73
  * @param cmdName - The command name to execute (e.g., `"serve"`, `"migrate"`)
73
74
  * @param cmdInfo - The merged command definition from {@link collectServiceCommands}
74
75
  * @param args - Parsed argument values keyed by argument name
75
76
  * @param services - Map of service name to service instance (from Core.getServices())
76
77
  * @param serviceFilter - Optional list of service names to filter to (supports suffix matching)
77
- * @returns `0` on success, `1` if no services match the filter, a method is missing or no service instance ran
78
+ * @returns the highest exit code returned by the handlers (`0` on success), `1` if no services match the filter,
79
+ * a method is missing or no service instance ran
78
80
  *
79
81
  * @example
80
82
  * ```typescript
@@ -95,6 +97,13 @@ export async function executeServiceCommand(cmdName, cmdInfo, args, services, se
95
97
  const commandArgs = Object.keys(cmdInfo.args).map(argName => args[argName] !== undefined ? args[argName] : cmdInfo.args[argName].default);
96
98
  // Count executed handlers: a command where every provider was skipped did nothing
97
99
  let executed = 0;
100
+ // Highest exit code returned by a handler
101
+ let exitCode = 0;
102
+ const recordExitCode = (result) => {
103
+ if (typeof result === "number" && result > exitCode) {
104
+ exitCode = result;
105
+ }
106
+ };
98
107
  // Long-running handlers (serve, worker) return a cancelable promise that stays
99
108
  // pending while they run: start them all, then wait for every one to settle.
100
109
  const running = [];
@@ -137,7 +146,7 @@ export async function executeServiceCommand(cmdName, cmdInfo, args, services, se
137
146
  running.push(result);
138
147
  }
139
148
  else {
140
- await result;
149
+ recordExitCode(await result);
141
150
  }
142
151
  executed++;
143
152
  }
@@ -151,12 +160,12 @@ export async function executeServiceCommand(cmdName, cmdInfo, args, services, se
151
160
  return 1;
152
161
  }
153
162
  // Cancelling a long-running command (SIGINT, SIGTERM) is a clean stop
154
- await Promise.all(running.map(p => Promise.resolve(p).catch(err => {
163
+ await Promise.all(running.map(p => Promise.resolve(p).then(recordExitCode, err => {
155
164
  if (err !== "Cancelled") {
156
165
  throw err;
157
166
  }
158
167
  })));
159
- return 0;
168
+ return exitCode;
160
169
  }
161
170
  /**
162
171
  * Whether a command handler returned a long-running cancelable promise
@@ -1 +1 @@
1
- {"version":3,"file":"servicecommands.js","sourceRoot":"","sources":["../../src/services/servicecommands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"servicecommands.js","sourceRoot":"","sources":["../../src/services/servicecommands.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { CryptoService } from "../services/cryptoservice.service.js";
1
+ import { type CryptoService } from "../services/cryptoservice.service.js";
2
2
  import { JWTOptions } from "../services/icryptoservice.js";
3
3
  import { Service } from "../services/service.js";
4
4
  import { CookieOptions } from "./cookie.js";
@@ -51,6 +51,8 @@ export declare class SessionModel extends UuidModel {
51
51
  export declare class CookieSessionParameters extends ServiceParameters {
52
52
  /**
53
53
  * Options for issue JWT token
54
+ *
55
+ * `secretOrPublicKey` can be encrypted with `webda config encrypt`
54
56
  */
55
57
  jwt?: JWTOptions;
56
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"manager.model.d.ts","sourceRoot":"","sources":["../../src/session/manager.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAU,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAgB,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE5E;;GAEG;AACH,8BAAsB,cAAc,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACtG;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;OAKG;IACG,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;IAED;;;;;;;OAOG;IACH,UAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAY7D;CACF;AAED,2DAA2D;AAC3D,qBAAa,YAAa,SAAQ,SAAS;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,GAAG,CAAC;IACb;;OAEG;IACH,YAAY,IAAI,EAAE,GAAG,EAIpB;CACF;AAED,sDAAsD;AACtD,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D;;OAEG;IACH,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB;;OAEG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,MAAM,GAAE,GAAQ,GAAG,IAAI,CAI3B;CACF;AAED;;;;;;;GAOG;AACH,qBAAa,oBAAoB,CAC/B,CAAC,SAAS,uBAAuB,GAAG,uBAAuB,CAC3D,SAAQ,cAAc,CAAC,CAAC,CAAC;IAEzB,aAAa,EAAE,aAAa,CAAC;IAE7B,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnD;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAyB7C;IAED;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,iBAgC5C;CACF"}
1
+ {"version":3,"file":"manager.model.d.ts","sourceRoot":"","sources":["../../src/session/manager.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,sCAAsC,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAU,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAgB,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE5E;;GAEG;AACH,8BAAsB,cAAc,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACtG;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;OAKG;IACG,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;IAED;;;;;;;OAOG;IACH,UAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAY7D;CACF;AAED,2DAA2D;AAC3D,qBAAa,YAAa,SAAQ,SAAS;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,GAAG,CAAC;IACb;;OAEG;IACH,YAAY,IAAI,EAAE,GAAG,EAIpB;CACF;AAED,sDAAsD;AACtD,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D;;;;OAIG;IACH,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB;;OAEG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,MAAM,GAAE,GAAQ,GAAG,IAAI,CAI3B;CACF;AAED;;;;;;;GAOG;AACH,qBAAa,oBAAoB,CAC/B,CAAC,SAAS,uBAAuB,GAAG,uBAAuB,CAC3D,SAAQ,cAAc,CAAC,CAAC,CAAC;IAEzB,aAAa,EAAE,aAAa,CAAC;IAE7B,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnD;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CA8B7C;IAED;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,iBAsC5C;CACF"}
@@ -32,6 +32,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
+ import { SecretString } from "../services/cryptoservice.service.js";
35
36
  import { Inject, Service } from "../services/service.js";
36
37
  import { CookieOptions, SecureCookie } from "./cookie.js";
37
38
  import { isWebContext } from "../contexts/icontext.js";
@@ -106,6 +107,8 @@ export class SessionModel extends UuidModel {
106
107
  export class CookieSessionParameters extends ServiceParameters {
107
108
  /**
108
109
  * Options for issue JWT token
110
+ *
111
+ * `secretOrPublicKey` can be encrypted with `webda config encrypt`
109
112
  */
110
113
  jwt;
111
114
  /**
@@ -158,7 +161,7 @@ let CookieSessionManager = (() => {
158
161
  return this.loadFromToken(context, authorization.substring(7).trim());
159
162
  }
160
163
  const session = new Session();
161
- const cookie = await SecureCookie.load(this.parameters.cookie.name, session, context, this.parameters.jwt);
164
+ const cookie = await SecureCookie.load(this.parameters.cookie.name, session, context, SecretString.unwrap(this.parameters.jwt));
162
165
  if (this.sessionModel) {
163
166
  if (cookie.sub) {
164
167
  Object.assign(session, (await this.sessionModel.get(cookie.sub))?.session);
@@ -201,10 +204,10 @@ let CookieSessionManager = (() => {
201
204
  ttl: Date.now() + this.parameters.cookie.maxAge * 1000
202
205
  });
203
206
  }
204
- SecureCookie.save(this.parameters.cookie.name, context, {}, { ...this.parameters.jwt, subject: session.uuid.toString() }, this.parameters.cookie);
207
+ SecureCookie.save(this.parameters.cookie.name, context, {}, SecretString.unwrap({ ...this.parameters.jwt, subject: session.uuid.toString() }), this.parameters.cookie);
205
208
  return;
206
209
  }
207
- SecureCookie.save(this.parameters.cookie.name, context, session, this.parameters.jwt, this.parameters.cookie);
210
+ SecureCookie.save(this.parameters.cookie.name, context, session, SecretString.unwrap(this.parameters.jwt), this.parameters.cookie);
208
211
  }
209
212
  };
210
213
  })();