@dyrected/core 2.6.2 → 2.6.4
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/dist/__tests__/access-features.test.d.ts +2 -0
- package/dist/__tests__/access-features.test.d.ts.map +1 -0
- package/dist/__tests__/access-features.test.js +159 -0
- package/dist/__tests__/access-features.test.js.map +1 -0
- package/dist/__tests__/access-parity.test.d.ts +2 -0
- package/dist/__tests__/access-parity.test.d.ts.map +1 -0
- package/dist/__tests__/access-parity.test.js +338 -0
- package/dist/__tests__/access-parity.test.js.map +1 -0
- package/dist/__tests__/access.test.d.ts +2 -0
- package/dist/__tests__/access.test.d.ts.map +1 -0
- package/dist/__tests__/access.test.js +137 -0
- package/dist/__tests__/access.test.js.map +1 -0
- package/dist/__tests__/admin-auth.test.d.ts +2 -0
- package/dist/__tests__/admin-auth.test.d.ts.map +1 -0
- package/dist/__tests__/admin-auth.test.js +440 -0
- package/dist/__tests__/admin-auth.test.js.map +1 -0
- package/dist/__tests__/app.test.d.ts +2 -0
- package/dist/__tests__/app.test.d.ts.map +1 -0
- package/dist/__tests__/app.test.js +112 -0
- package/dist/__tests__/app.test.js.map +1 -0
- package/dist/__tests__/audit.test.d.ts +2 -0
- package/dist/__tests__/audit.test.d.ts.map +1 -0
- package/dist/__tests__/audit.test.js +125 -0
- package/dist/__tests__/audit.test.js.map +1 -0
- package/dist/__tests__/auth-hydration.test.d.ts +2 -0
- package/dist/__tests__/auth-hydration.test.d.ts.map +1 -0
- package/dist/__tests__/auth-hydration.test.js +90 -0
- package/dist/__tests__/auth-hydration.test.js.map +1 -0
- package/dist/__tests__/auth-invite.test.d.ts +2 -0
- package/dist/__tests__/auth-invite.test.d.ts.map +1 -0
- package/dist/__tests__/auth-invite.test.js +152 -0
- package/dist/__tests__/auth-invite.test.js.map +1 -0
- package/dist/__tests__/auth-lockout.test.d.ts +2 -0
- package/dist/__tests__/auth-lockout.test.d.ts.map +1 -0
- package/dist/__tests__/auth-lockout.test.js +154 -0
- package/dist/__tests__/auth-lockout.test.js.map +1 -0
- package/dist/__tests__/auth-sessions.test.d.ts +2 -0
- package/dist/__tests__/auth-sessions.test.d.ts.map +1 -0
- package/dist/__tests__/auth-sessions.test.js +118 -0
- package/dist/__tests__/auth-sessions.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +402 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/define-field.test.d.ts +2 -0
- package/dist/__tests__/define-field.test.d.ts.map +1 -0
- package/dist/__tests__/define-field.test.js +121 -0
- package/dist/__tests__/define-field.test.js.map +1 -0
- package/dist/__tests__/deleteMany.test.d.ts +2 -0
- package/dist/__tests__/deleteMany.test.d.ts.map +1 -0
- package/dist/__tests__/deleteMany.test.js +75 -0
- package/dist/__tests__/deleteMany.test.js.map +1 -0
- package/dist/__tests__/depth.test.d.ts +2 -0
- package/dist/__tests__/depth.test.d.ts.map +1 -0
- package/dist/__tests__/depth.test.js +115 -0
- package/dist/__tests__/depth.test.js.map +1 -0
- package/dist/__tests__/dynamic-options.test.d.ts +2 -0
- package/dist/__tests__/dynamic-options.test.d.ts.map +1 -0
- package/dist/__tests__/dynamic-options.test.js +168 -0
- package/dist/__tests__/dynamic-options.test.js.map +1 -0
- package/dist/__tests__/email.service.test.d.ts +2 -0
- package/dist/__tests__/email.service.test.d.ts.map +1 -0
- package/dist/__tests__/email.service.test.js +52 -0
- package/dist/__tests__/email.service.test.js.map +1 -0
- package/dist/__tests__/field-inference.test-types.d.ts +161 -0
- package/dist/__tests__/field-inference.test-types.d.ts.map +1 -0
- package/dist/__tests__/field-inference.test-types.js +87 -0
- package/dist/__tests__/field-inference.test-types.js.map +1 -0
- package/dist/__tests__/fixtures/editorial-workflow.d.ts +14 -0
- package/dist/__tests__/fixtures/editorial-workflow.d.ts.map +1 -0
- package/dist/__tests__/fixtures/editorial-workflow.js +12 -0
- package/dist/__tests__/fixtures/editorial-workflow.js.map +1 -0
- package/dist/__tests__/hooks.test.d.ts +2 -0
- package/dist/__tests__/hooks.test.d.ts.map +1 -0
- package/dist/__tests__/hooks.test.js +320 -0
- package/dist/__tests__/hooks.test.js.map +1 -0
- package/dist/__tests__/mocks.d.ts +75 -0
- package/dist/__tests__/mocks.d.ts.map +1 -0
- package/dist/__tests__/mocks.js +170 -0
- package/dist/__tests__/mocks.js.map +1 -0
- package/dist/__tests__/observability.test.d.ts +2 -0
- package/dist/__tests__/observability.test.d.ts.map +1 -0
- package/dist/__tests__/observability.test.js +233 -0
- package/dist/__tests__/observability.test.js.map +1 -0
- package/dist/__tests__/openapi.test.d.ts +2 -0
- package/dist/__tests__/openapi.test.d.ts.map +1 -0
- package/dist/__tests__/openapi.test.js +105 -0
- package/dist/__tests__/openapi.test.js.map +1 -0
- package/dist/__tests__/parse-sort.test.d.ts +2 -0
- package/dist/__tests__/parse-sort.test.d.ts.map +1 -0
- package/dist/__tests__/parse-sort.test.js +24 -0
- package/dist/__tests__/parse-sort.test.js.map +1 -0
- package/dist/__tests__/preferences.test.d.ts +2 -0
- package/dist/__tests__/preferences.test.d.ts.map +1 -0
- package/dist/__tests__/preferences.test.js +168 -0
- package/dist/__tests__/preferences.test.js.map +1 -0
- package/dist/__tests__/router.test.d.ts +2 -0
- package/dist/__tests__/router.test.d.ts.map +1 -0
- package/dist/__tests__/router.test.js +70 -0
- package/dist/__tests__/router.test.js.map +1 -0
- package/dist/__tests__/search.test.d.ts +2 -0
- package/dist/__tests__/search.test.d.ts.map +1 -0
- package/dist/__tests__/search.test.js +174 -0
- package/dist/__tests__/search.test.js.map +1 -0
- package/dist/__tests__/upload-validation.test.d.ts +2 -0
- package/dist/__tests__/upload-validation.test.d.ts.map +1 -0
- package/dist/__tests__/upload-validation.test.js +41 -0
- package/dist/__tests__/upload-validation.test.js.map +1 -0
- package/dist/__tests__/where.test.d.ts +2 -0
- package/dist/__tests__/where.test.d.ts.map +1 -0
- package/dist/__tests__/where.test.js +105 -0
- package/dist/__tests__/where.test.js.map +1 -0
- package/dist/__tests__/workflow.test.d.ts +2 -0
- package/dist/__tests__/workflow.test.d.ts.map +1 -0
- package/dist/__tests__/workflow.test.js +684 -0
- package/dist/__tests__/workflow.test.js.map +1 -0
- package/dist/app-config-C9VJ6rTv.d.cts +2092 -0
- package/dist/app-config-C9VJ6rTv.d.ts +2092 -0
- package/dist/app-config-CYV70eoF.d.cts +2100 -0
- package/dist/app-config-CYV70eoF.d.ts +2100 -0
- package/dist/app.d.ts +35 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +164 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/access.d.ts +5 -0
- package/dist/auth/access.d.ts.map +1 -0
- package/dist/auth/access.js +59 -0
- package/dist/auth/access.js.map +1 -0
- package/dist/auth/jexl.d.ts +13 -0
- package/dist/auth/jexl.d.ts.map +1 -0
- package/dist/auth/jexl.js +30 -0
- package/dist/auth/jexl.js.map +1 -0
- package/dist/auth/lockout.d.ts +11 -0
- package/dist/auth/lockout.d.ts.map +1 -0
- package/dist/auth/lockout.js +37 -0
- package/dist/auth/lockout.js.map +1 -0
- package/dist/auth/password.d.ts +10 -0
- package/dist/auth/password.d.ts.map +1 -0
- package/dist/auth/password.js +28 -0
- package/dist/auth/password.js.map +1 -0
- package/dist/auth/sessions.d.ts +39 -0
- package/dist/auth/sessions.d.ts.map +1 -0
- package/dist/auth/sessions.js +126 -0
- package/dist/auth/sessions.js.map +1 -0
- package/dist/auth/token.d.ts +23 -0
- package/dist/auth/token.d.ts.map +1 -0
- package/dist/auth/token.js +40 -0
- package/dist/auth/token.js.map +1 -0
- package/dist/chunk-23NM4LDU.js +2883 -0
- package/dist/chunk-2TKDCCIR.js +2622 -0
- package/dist/chunk-3SFITPX4.js +2628 -0
- package/dist/chunk-CQVTQ67D.js +2632 -0
- package/dist/chunk-ELHRRPKX.js +2863 -0
- package/dist/chunk-HRLSFTLR.js +3061 -0
- package/dist/chunk-QTIAQBNH.js +3097 -0
- package/dist/chunk-T2DGC4MD.js +3008 -0
- package/dist/chunk-TLU77TLE.js +3203 -0
- package/dist/chunk-YEBCT77K.js +3269 -0
- package/dist/chunk-YXEKNN5X.js +3085 -0
- package/dist/controllers/admin-auth.controller.d.ts +71 -0
- package/dist/controllers/admin-auth.controller.d.ts.map +1 -0
- package/dist/controllers/admin-auth.controller.js +450 -0
- package/dist/controllers/admin-auth.controller.js.map +1 -0
- package/dist/controllers/audit.controller.d.ts +42 -0
- package/dist/controllers/audit.controller.d.ts.map +1 -0
- package/dist/controllers/audit.controller.js +149 -0
- package/dist/controllers/audit.controller.js.map +1 -0
- package/dist/controllers/auth.controller.d.ts +143 -0
- package/dist/controllers/auth.controller.d.ts.map +1 -0
- package/dist/controllers/auth.controller.js +572 -0
- package/dist/controllers/auth.controller.js.map +1 -0
- package/dist/controllers/collection.controller.d.ts +170 -0
- package/dist/controllers/collection.controller.d.ts.map +1 -0
- package/dist/controllers/collection.controller.js +1033 -0
- package/dist/controllers/collection.controller.js.map +1 -0
- package/dist/controllers/global.controller.d.ts +20 -0
- package/dist/controllers/global.controller.d.ts.map +1 -0
- package/dist/controllers/global.controller.js +182 -0
- package/dist/controllers/global.controller.js.map +1 -0
- package/dist/controllers/media.controller.d.ts +39 -0
- package/dist/controllers/media.controller.d.ts.map +1 -0
- package/dist/controllers/media.controller.js +178 -0
- package/dist/controllers/media.controller.js.map +1 -0
- package/dist/controllers/preview.controller.d.ts +37 -0
- package/dist/controllers/preview.controller.d.ts.map +1 -0
- package/dist/controllers/preview.controller.js +48 -0
- package/dist/controllers/preview.controller.js.map +1 -0
- package/dist/index.cjs +707 -27
- package/dist/index.d.cts +77 -5
- package/dist/index.d.ts +77 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +19 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +157 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +9 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +75 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/network.d.ts +6 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +70 -0
- package/dist/network.js.map +1 -0
- package/dist/observability.d.ts +113 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +497 -0
- package/dist/observability.js.map +1 -0
- package/dist/router.d.ts +8 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +704 -0
- package/dist/router.js.map +1 -0
- package/dist/server.cjs +861 -54
- package/dist/server.d.cts +9 -1
- package/dist/server.d.ts +9 -1
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +189 -26
- package/dist/server.js.map +1 -0
- package/dist/services/audit.service.d.ts +23 -0
- package/dist/services/audit.service.d.ts.map +1 -0
- package/dist/services/audit.service.js +39 -0
- package/dist/services/audit.service.js.map +1 -0
- package/dist/services/defaults.service.d.ts +8 -0
- package/dist/services/defaults.service.d.ts.map +1 -0
- package/dist/services/defaults.service.js +55 -0
- package/dist/services/defaults.service.js.map +1 -0
- package/dist/services/email-template.d.ts +46 -0
- package/dist/services/email-template.d.ts.map +1 -0
- package/dist/services/email-template.js +88 -0
- package/dist/services/email-template.js.map +1 -0
- package/dist/services/email.service.d.ts +34 -0
- package/dist/services/email.service.d.ts.map +1 -0
- package/dist/services/email.service.js +129 -0
- package/dist/services/email.service.js.map +1 -0
- package/dist/services/media.service.d.ts +20 -0
- package/dist/services/media.service.d.ts.map +1 -0
- package/dist/services/media.service.js +49 -0
- package/dist/services/media.service.js.map +1 -0
- package/dist/services/population.service.d.ts +20 -0
- package/dist/services/population.service.d.ts.map +1 -0
- package/dist/services/population.service.js +224 -0
- package/dist/services/population.service.js.map +1 -0
- package/dist/types/access.d.ts +48 -0
- package/dist/types/access.d.ts.map +1 -0
- package/dist/types/access.js +2 -0
- package/dist/types/access.js.map +1 -0
- package/dist/types/adapters.d.ts +152 -0
- package/dist/types/adapters.d.ts.map +1 -0
- package/dist/types/adapters.js +2 -0
- package/dist/types/adapters.js.map +1 -0
- package/dist/types/admin-auth.d.ts +132 -0
- package/dist/types/admin-auth.d.ts.map +1 -0
- package/dist/types/admin-auth.js +2 -0
- package/dist/types/admin-auth.js.map +1 -0
- package/dist/types/admin.d.ts +86 -0
- package/dist/types/admin.d.ts.map +1 -0
- package/dist/types/admin.js +2 -0
- package/dist/types/admin.js.map +1 -0
- package/dist/types/app-config.d.ts +279 -0
- package/dist/types/app-config.d.ts.map +1 -0
- package/dist/types/app-config.js +2 -0
- package/dist/types/app-config.js.map +1 -0
- package/dist/types/documents.d.ts +65 -0
- package/dist/types/documents.d.ts.map +1 -0
- package/dist/types/documents.js +2 -0
- package/dist/types/documents.js.map +1 -0
- package/dist/types/hooks.d.ts +122 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/hooks.js +2 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/request.d.ts +42 -0
- package/dist/types/request.d.ts.map +1 -0
- package/dist/types/request.js +2 -0
- package/dist/types/request.js.map +1 -0
- package/dist/types/schema-config.d.ts +443 -0
- package/dist/types/schema-config.d.ts.map +1 -0
- package/dist/types/schema-config.js +2 -0
- package/dist/types/schema-config.js.map +1 -0
- package/dist/types/schema-core.d.ts +628 -0
- package/dist/types/schema-core.d.ts.map +1 -0
- package/dist/types/schema-core.js +2 -0
- package/dist/types/schema-core.js.map +1 -0
- package/dist/types/schema-inference.d.ts +73 -0
- package/dist/types/schema-inference.d.ts.map +1 -0
- package/dist/types/schema-inference.js +2 -0
- package/dist/types/schema-inference.js.map +1 -0
- package/dist/types/workflows.d.ts +121 -0
- package/dist/types/workflows.d.ts.map +1 -0
- package/dist/types/workflows.js +7 -0
- package/dist/types/workflows.js.map +1 -0
- package/dist/utils/access-control.d.ts +35 -0
- package/dist/utils/access-control.d.ts.map +1 -0
- package/dist/utils/access-control.js +161 -0
- package/dist/utils/access-control.js.map +1 -0
- package/dist/utils/admin-auth.d.ts +5 -0
- package/dist/utils/admin-auth.d.ts.map +1 -0
- package/dist/utils/admin-auth.js +39 -0
- package/dist/utils/admin-auth.js.map +1 -0
- package/dist/utils/block-references.d.ts +10 -0
- package/dist/utils/block-references.d.ts.map +1 -0
- package/dist/utils/block-references.js +100 -0
- package/dist/utils/block-references.js.map +1 -0
- package/dist/utils/collection-search.d.ts +11 -0
- package/dist/utils/collection-search.d.ts.map +1 -0
- package/dist/utils/collection-search.js +204 -0
- package/dist/utils/collection-search.js.map +1 -0
- package/dist/utils/config.d.ts +8 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +336 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/hooks.d.ts +41 -0
- package/dist/utils/hooks.d.ts.map +1 -0
- package/dist/utils/hooks.js +177 -0
- package/dist/utils/hooks.js.map +1 -0
- package/dist/utils/openapi.d.ts +6 -0
- package/dist/utils/openapi.d.ts.map +1 -0
- package/dist/utils/openapi.js +981 -0
- package/dist/utils/openapi.js.map +1 -0
- package/dist/utils/parse-sort.d.ts +43 -0
- package/dist/utils/parse-sort.d.ts.map +1 -0
- package/dist/utils/parse-sort.js +70 -0
- package/dist/utils/parse-sort.js.map +1 -0
- package/dist/utils/parse-where.d.ts +69 -0
- package/dist/utils/parse-where.d.ts.map +1 -0
- package/dist/utils/parse-where.js +202 -0
- package/dist/utils/parse-where.js.map +1 -0
- package/dist/utils/readonly-db.d.ts +9 -0
- package/dist/utils/readonly-db.d.ts.map +1 -0
- package/dist/utils/readonly-db.js +21 -0
- package/dist/utils/readonly-db.js.map +1 -0
- package/dist/utils/swagger.d.ts +11 -0
- package/dist/utils/swagger.d.ts.map +1 -0
- package/dist/utils/swagger.js +62 -0
- package/dist/utils/swagger.js.map +1 -0
- package/dist/utils/upload-validation.d.ts +23 -0
- package/dist/utils/upload-validation.d.ts.map +1 -0
- package/dist/utils/upload-validation.js +46 -0
- package/dist/utils/upload-validation.js.map +1 -0
- package/dist/utils/where-sanitizer.d.ts +10 -0
- package/dist/utils/where-sanitizer.d.ts.map +1 -0
- package/dist/utils/where-sanitizer.js +67 -0
- package/dist/utils/where-sanitizer.js.map +1 -0
- package/dist/workflows.d.ts +86 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +405 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +1 -1
package/dist/server.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ import * as hono_types from 'hono/types';
|
|
|
2
2
|
import * as hono from 'hono';
|
|
3
3
|
import { Hono, Context } from 'hono';
|
|
4
4
|
import { Logger } from 'pino';
|
|
5
|
-
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-
|
|
5
|
+
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-CYV70eoF.cjs';
|
|
6
6
|
import { JWTPayload } from 'jose';
|
|
7
7
|
import { Tracer, Counter, Attributes, Histogram, Span } from '@opentelemetry/api';
|
|
8
8
|
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
|
|
@@ -153,6 +153,9 @@ declare class AuthController {
|
|
|
153
153
|
private collection;
|
|
154
154
|
constructor(collection: CollectionConfig);
|
|
155
155
|
private sanitizeUser;
|
|
156
|
+
private hasField;
|
|
157
|
+
private buildPendingInviteData;
|
|
158
|
+
private buildAcceptedInviteData;
|
|
156
159
|
private clearLockoutState;
|
|
157
160
|
private recordFailedLogin;
|
|
158
161
|
init(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
@@ -185,6 +188,9 @@ declare class AuthController {
|
|
|
185
188
|
}, 401, "json">) | (Response & hono.TypedResponse<{
|
|
186
189
|
error: true;
|
|
187
190
|
message: string;
|
|
191
|
+
}, 403, "json">) | (Response & hono.TypedResponse<{
|
|
192
|
+
error: true;
|
|
193
|
+
message: string;
|
|
188
194
|
retryAfterSeconds: number;
|
|
189
195
|
}, 429, "json">) | (Response & hono.TypedResponse<{
|
|
190
196
|
token: string;
|
|
@@ -251,6 +257,8 @@ declare class AuthController {
|
|
|
251
257
|
}, 409, "json">) | (Response & hono.TypedResponse<{
|
|
252
258
|
success: true;
|
|
253
259
|
message: string;
|
|
260
|
+
token: string;
|
|
261
|
+
inviteUrl: string | undefined;
|
|
254
262
|
}, hono_utils_http_status.ContentfulStatusCode, "json">)>;
|
|
255
263
|
acceptInvite(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
256
264
|
message: string;
|
package/dist/server.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as hono_types from 'hono/types';
|
|
|
2
2
|
import * as hono from 'hono';
|
|
3
3
|
import { Hono, Context } from 'hono';
|
|
4
4
|
import { Logger } from 'pino';
|
|
5
|
-
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-
|
|
5
|
+
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-CYV70eoF.js';
|
|
6
6
|
import { JWTPayload } from 'jose';
|
|
7
7
|
import { Tracer, Counter, Attributes, Histogram, Span } from '@opentelemetry/api';
|
|
8
8
|
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
|
|
@@ -153,6 +153,9 @@ declare class AuthController {
|
|
|
153
153
|
private collection;
|
|
154
154
|
constructor(collection: CollectionConfig);
|
|
155
155
|
private sanitizeUser;
|
|
156
|
+
private hasField;
|
|
157
|
+
private buildPendingInviteData;
|
|
158
|
+
private buildAcceptedInviteData;
|
|
156
159
|
private clearLockoutState;
|
|
157
160
|
private recordFailedLogin;
|
|
158
161
|
init(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
@@ -185,6 +188,9 @@ declare class AuthController {
|
|
|
185
188
|
}, 401, "json">) | (Response & hono.TypedResponse<{
|
|
186
189
|
error: true;
|
|
187
190
|
message: string;
|
|
191
|
+
}, 403, "json">) | (Response & hono.TypedResponse<{
|
|
192
|
+
error: true;
|
|
193
|
+
message: string;
|
|
188
194
|
retryAfterSeconds: number;
|
|
189
195
|
}, 429, "json">) | (Response & hono.TypedResponse<{
|
|
190
196
|
token: string;
|
|
@@ -251,6 +257,8 @@ declare class AuthController {
|
|
|
251
257
|
}, 409, "json">) | (Response & hono.TypedResponse<{
|
|
252
258
|
success: true;
|
|
253
259
|
message: string;
|
|
260
|
+
token: string;
|
|
261
|
+
inviteUrl: string | undefined;
|
|
254
262
|
}, hono_utils_http_status.ContentfulStatusCode, "json">)>;
|
|
255
263
|
acceptInvite(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
256
264
|
message: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WORKFLOW_HISTORY_COLLECTION,
|
|
3
|
+
assertValidAdminConditionsInConfig,
|
|
4
|
+
assertValidDeclarativeAccessInConfig,
|
|
5
|
+
assertValidDeclarativeHooksInConfig,
|
|
6
|
+
assertValidPreviewUrlsInConfig,
|
|
3
7
|
attachRequestMetrics,
|
|
4
8
|
bindObservabilityRuntime,
|
|
5
9
|
buildRequestLogger,
|
|
6
10
|
canViewWorkflowDraft,
|
|
7
11
|
captureRequestBody,
|
|
12
|
+
collectConfigDiagnostics,
|
|
8
13
|
createObservabilityRuntime,
|
|
9
14
|
createRequestSpan,
|
|
10
15
|
createWorkflowDocument,
|
|
@@ -36,7 +41,7 @@ import {
|
|
|
36
41
|
touchAuthSession,
|
|
37
42
|
transitionWorkflow,
|
|
38
43
|
verifyCollectionToken
|
|
39
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-YEBCT77K.js";
|
|
40
45
|
|
|
41
46
|
// src/app.ts
|
|
42
47
|
import { Hono } from "hono";
|
|
@@ -985,6 +990,10 @@ var CollectionController = class {
|
|
|
985
990
|
query: where,
|
|
986
991
|
user,
|
|
987
992
|
db: readonlyDb
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
surface: "collection.beforeRead",
|
|
996
|
+
path: `collection:${this.collection.slug}.hooks.beforeRead`
|
|
988
997
|
}
|
|
989
998
|
);
|
|
990
999
|
if (beforeReadResult !== void 0) {
|
|
@@ -1267,6 +1276,9 @@ var CollectionController = class {
|
|
|
1267
1276
|
user,
|
|
1268
1277
|
operation: "create",
|
|
1269
1278
|
db: readonlyDb
|
|
1279
|
+
}, {
|
|
1280
|
+
surface: "collection.beforeChange",
|
|
1281
|
+
path: `collection:${this.collection.slug}.hooks.beforeChange`
|
|
1270
1282
|
});
|
|
1271
1283
|
const doc = this.collection.workflow ? (await createWorkflowDocument({
|
|
1272
1284
|
config,
|
|
@@ -1301,6 +1313,9 @@ var CollectionController = class {
|
|
|
1301
1313
|
req: c.req,
|
|
1302
1314
|
user,
|
|
1303
1315
|
db: readonlyDb
|
|
1316
|
+
}, {
|
|
1317
|
+
surface: "collection.afterRead",
|
|
1318
|
+
path: `collection:${this.collection.slug}.hooks.afterRead`
|
|
1304
1319
|
});
|
|
1305
1320
|
const finalDoc = await executeFieldAfterRead(
|
|
1306
1321
|
this.collection.fields,
|
|
@@ -1398,6 +1413,9 @@ var CollectionController = class {
|
|
|
1398
1413
|
user,
|
|
1399
1414
|
operation: "create",
|
|
1400
1415
|
db: readonlyDb
|
|
1416
|
+
}, {
|
|
1417
|
+
surface: "collection.beforeChange",
|
|
1418
|
+
path: `collection:${this.collection.slug}.hooks.beforeChange`
|
|
1401
1419
|
});
|
|
1402
1420
|
const doc = await db.create({
|
|
1403
1421
|
collection: this.collection.slug,
|
|
@@ -1420,6 +1438,9 @@ var CollectionController = class {
|
|
|
1420
1438
|
req: c.req,
|
|
1421
1439
|
user,
|
|
1422
1440
|
db: readonlyDb
|
|
1441
|
+
}, {
|
|
1442
|
+
surface: "collection.afterRead",
|
|
1443
|
+
path: `collection:${this.collection.slug}.hooks.afterRead`
|
|
1423
1444
|
});
|
|
1424
1445
|
const finalDoc = await executeFieldAfterRead(
|
|
1425
1446
|
this.collection.fields,
|
|
@@ -1528,6 +1549,9 @@ var CollectionController = class {
|
|
|
1528
1549
|
user,
|
|
1529
1550
|
operation: "update",
|
|
1530
1551
|
db: readonlyDb
|
|
1552
|
+
}, {
|
|
1553
|
+
surface: "collection.beforeChange",
|
|
1554
|
+
path: `collection:${this.collection.slug}.hooks.beforeChange`
|
|
1531
1555
|
});
|
|
1532
1556
|
const doc = this.collection.workflow ? (await saveWorkflowDraft({
|
|
1533
1557
|
config,
|
|
@@ -1565,6 +1589,9 @@ var CollectionController = class {
|
|
|
1565
1589
|
req: c.req,
|
|
1566
1590
|
user,
|
|
1567
1591
|
db: readonlyDb
|
|
1592
|
+
}, {
|
|
1593
|
+
surface: "collection.afterRead",
|
|
1594
|
+
path: `collection:${this.collection.slug}.hooks.afterRead`
|
|
1568
1595
|
});
|
|
1569
1596
|
const finalDoc = await executeFieldAfterRead(
|
|
1570
1597
|
this.collection.fields,
|
|
@@ -1959,6 +1986,9 @@ var GlobalController = class {
|
|
|
1959
1986
|
query: void 0,
|
|
1960
1987
|
user,
|
|
1961
1988
|
db: readonlyDb
|
|
1989
|
+
}, {
|
|
1990
|
+
surface: "global.beforeRead",
|
|
1991
|
+
path: `global:${this.global.slug}.hooks.beforeRead`
|
|
1962
1992
|
});
|
|
1963
1993
|
let data = await db.getGlobal({ slug: this.global.slug });
|
|
1964
1994
|
const isEmpty = !data || isFunctionallyEmpty(data);
|
|
@@ -1996,6 +2026,10 @@ var GlobalController = class {
|
|
|
1996
2026
|
req: c.req,
|
|
1997
2027
|
user,
|
|
1998
2028
|
db: readonlyDb
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
surface: "global.afterRead",
|
|
2032
|
+
path: `global:${this.global.slug}.hooks.afterRead`
|
|
1999
2033
|
}
|
|
2000
2034
|
);
|
|
2001
2035
|
const docWithFieldHooks = await executeFieldAfterRead(
|
|
@@ -2078,6 +2112,9 @@ var GlobalController = class {
|
|
|
2078
2112
|
user,
|
|
2079
2113
|
operation: "update",
|
|
2080
2114
|
db: readonlyDb
|
|
2115
|
+
}, {
|
|
2116
|
+
surface: "global.beforeChange",
|
|
2117
|
+
path: `global:${this.global.slug}.hooks.beforeChange`
|
|
2081
2118
|
});
|
|
2082
2119
|
const updated = await db.updateGlobal({ slug: this.global.slug, data });
|
|
2083
2120
|
await runCollectionHooks(
|
|
@@ -2097,6 +2134,9 @@ var GlobalController = class {
|
|
|
2097
2134
|
req: c.req,
|
|
2098
2135
|
user,
|
|
2099
2136
|
db: readonlyDb
|
|
2137
|
+
}, {
|
|
2138
|
+
surface: "global.afterRead",
|
|
2139
|
+
path: `global:${this.global.slug}.hooks.afterRead`
|
|
2100
2140
|
});
|
|
2101
2141
|
const finalDoc = await executeFieldAfterRead(
|
|
2102
2142
|
this.global.fields,
|
|
@@ -2317,6 +2357,9 @@ var MediaController = class {
|
|
|
2317
2357
|
}
|
|
2318
2358
|
};
|
|
2319
2359
|
|
|
2360
|
+
// src/controllers/auth.controller.ts
|
|
2361
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
2362
|
+
|
|
2320
2363
|
// src/auth/lockout.ts
|
|
2321
2364
|
var DEFAULT_MAX_LOGIN_ATTEMPTS = 5;
|
|
2322
2365
|
var DEFAULT_LOCK_TIME_MS = 10 * 60 * 1e3;
|
|
@@ -2361,6 +2404,7 @@ var emailTokens = {
|
|
|
2361
2404
|
border: "#dde0d7",
|
|
2362
2405
|
accent: "#b6ff2e",
|
|
2363
2406
|
code: "#f1f3ec",
|
|
2407
|
+
codeBorder: "#e2e5dc",
|
|
2364
2408
|
dangerSurface: "#fff2f0",
|
|
2365
2409
|
dangerBorder: "#ffc9c2",
|
|
2366
2410
|
dangerText: "#9f251b"
|
|
@@ -2410,7 +2454,13 @@ function table(content, style = "width:100%") {
|
|
|
2410
2454
|
}
|
|
2411
2455
|
function detailBox(content, monospace = false) {
|
|
2412
2456
|
const font = monospace ? emailTokens.mono : emailTokens.font;
|
|
2413
|
-
return table(
|
|
2457
|
+
return table(
|
|
2458
|
+
row(
|
|
2459
|
+
escapeHtml(content),
|
|
2460
|
+
`padding:14px 16px;font-family:${font};font-size:13px;line-height:1.5;font-weight:${monospace ? "400" : "700"};color:${emailTokens.colors.text};word-break:break-all`
|
|
2461
|
+
),
|
|
2462
|
+
`width:100%;background:${emailTokens.colors.code};border:1px solid ${emailTokens.colors.codeBorder};border-radius:${emailTokens.radius.control}`
|
|
2463
|
+
);
|
|
2414
2464
|
}
|
|
2415
2465
|
function ctaButton(label, href) {
|
|
2416
2466
|
const safeHref = safeHttpUrl(href);
|
|
@@ -2420,22 +2470,46 @@ function ctaButton(label, href) {
|
|
|
2420
2470
|
"padding:8px 0 24px"
|
|
2421
2471
|
), "width:auto");
|
|
2422
2472
|
}
|
|
2473
|
+
function safeLinkDetailBox(href) {
|
|
2474
|
+
const safeHref = safeHttpUrl(href);
|
|
2475
|
+
if (!safeHref) return "";
|
|
2476
|
+
return detailBox(safeHref, true);
|
|
2477
|
+
}
|
|
2423
2478
|
function alertBox(content) {
|
|
2424
2479
|
return table(row(escapeHtml(content), `padding:13px 16px;font-family:${emailTokens.font};font-size:13px;line-height:1.5;color:${emailTokens.colors.dangerText}`), `width:100%;background:${emailTokens.colors.dangerSurface};border:1px solid ${emailTokens.colors.dangerBorder};border-radius:${emailTokens.radius.control}`);
|
|
2425
2480
|
}
|
|
2426
2481
|
function layout({ preheader, title, content, footer }) {
|
|
2427
2482
|
return `<!doctype html>
|
|
2428
|
-
<html lang="en">
|
|
2429
|
-
<head
|
|
2430
|
-
|
|
2431
|
-
<
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2483
|
+
<html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
|
|
2484
|
+
<head>
|
|
2485
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
2486
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2487
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
2488
|
+
<meta name="x-apple-disable-message-reformatting">
|
|
2489
|
+
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
|
2490
|
+
<meta name="color-scheme" content="light">
|
|
2491
|
+
<meta name="supported-color-schemes" content="light">
|
|
2492
|
+
<title>${escapeHtml(title)}</title>
|
|
2493
|
+
</head>
|
|
2494
|
+
<body style="margin:0;padding:0;background-color:${emailTokens.colors.canvas};word-spacing:normal;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%">
|
|
2495
|
+
<div style="display:none;max-height:0;max-width:0;overflow:hidden;opacity:0;mso-hide:all;color:transparent;font-size:1px;line-height:1px">
|
|
2496
|
+
${escapeHtml(preheader)}​͏‌   ͏‌
|
|
2497
|
+
</div>
|
|
2498
|
+
<center lang="en" style="width:100%;background-color:${emailTokens.colors.canvas}">
|
|
2499
|
+
${table(
|
|
2500
|
+
row(
|
|
2501
|
+
table(
|
|
2502
|
+
row(" ", `height:5px;background:${emailTokens.colors.accent};font-size:0;line-height:0`) + row(`${sectionLabel("Dyrected")}${heading(title)}`, "padding:30px 32px 24px") + row(content, "padding:0 32px 32px") + row(
|
|
2503
|
+
`${divider()}${paragraph(footer, "20px 0 6px")}${paragraph("Privacy: this message contains account-related information; please avoid forwarding it.", "0")}`,
|
|
2504
|
+
"padding:0 32px 28px"
|
|
2505
|
+
),
|
|
2506
|
+
`width:100%;max-width:${emailTokens.width};background:${emailTokens.colors.surface};border:1px solid ${emailTokens.colors.border};border-radius:${emailTokens.radius.card};overflow:hidden`
|
|
2507
|
+
),
|
|
2508
|
+
"padding:32px 12px"
|
|
2436
2509
|
),
|
|
2437
|
-
|
|
2438
|
-
)
|
|
2510
|
+
`width:100%;background:${emailTokens.colors.canvas}`
|
|
2511
|
+
)}
|
|
2512
|
+
</center>
|
|
2439
2513
|
</body>
|
|
2440
2514
|
</html>`;
|
|
2441
2515
|
}
|
|
@@ -2521,12 +2595,14 @@ function buildWelcomeEmail(config, args) {
|
|
|
2521
2595
|
}
|
|
2522
2596
|
function buildInviteEmail(config, args) {
|
|
2523
2597
|
const custom = config.email?.templates?.invite?.(args);
|
|
2598
|
+
const inviteLink = args.url;
|
|
2599
|
+
const inviteLinkBlock = inviteLink ? safeLinkDetailBox(inviteLink) : "";
|
|
2524
2600
|
return {
|
|
2525
2601
|
subject: custom?.subject ?? "You've been invited",
|
|
2526
2602
|
html: custom?.html ?? layout({
|
|
2527
|
-
preheader: "You've been invited to join a Dyrected
|
|
2603
|
+
preheader: "You've been invited to join a Dyrected admin area.",
|
|
2528
2604
|
title: "You've been invited",
|
|
2529
|
-
content: `${args.invitedByEmail ? paragraph(`You were invited by ${args.invitedByEmail}.`) : ""}${paragraph("Use the token below to accept your invitation. It expires in 7 days.")}${sectionLabel("Invitation token")}${detailBox(args.token, true)}`,
|
|
2605
|
+
content: inviteLink ? `${args.invitedByEmail ? paragraph(`You were invited by ${args.invitedByEmail}.`) : ""}${paragraph("Use the invitation link below to create your account. The link expires in 7 days.")}${ctaButton("Accept invitation", inviteLink)}${sectionLabel("Invitation link")}${inviteLinkBlock}${paragraph("If the button does not work, copy and paste the link above into your browser.", "12px 0 0")}` : `${args.invitedByEmail ? paragraph(`You were invited by ${args.invitedByEmail}.`) : ""}${paragraph("Use the invitation token below to accept your invitation. It expires in 7 days.")}${sectionLabel("Invitation token")}${detailBox(args.token, true)}`,
|
|
2530
2606
|
footer: "If you weren't expecting this invitation, you can safely ignore this email."
|
|
2531
2607
|
})
|
|
2532
2608
|
};
|
|
@@ -2534,12 +2610,13 @@ function buildInviteEmail(config, args) {
|
|
|
2534
2610
|
function buildResetPasswordEmail(config, args) {
|
|
2535
2611
|
const custom = config.email?.templates?.resetPassword?.(args);
|
|
2536
2612
|
const resetLink = args.url;
|
|
2613
|
+
const resetLinkBlock = resetLink ? safeLinkDetailBox(resetLink) : "";
|
|
2537
2614
|
return {
|
|
2538
2615
|
subject: custom?.subject ?? "Reset your password",
|
|
2539
2616
|
html: custom?.html ?? layout({
|
|
2540
2617
|
preheader: "Reset your Dyrected password.",
|
|
2541
2618
|
title: "Reset your password",
|
|
2542
|
-
content: `${paragraph("We received a request to reset your password. The reset link
|
|
2619
|
+
content: resetLink ? `${paragraph("We received a request to reset your password. The reset link expires in 1 hour.")}${ctaButton("Reset password", resetLink)}${sectionLabel("Reset link")}${resetLinkBlock}${paragraph("If the button does not work, copy and paste the link above into your browser.", "12px 0 0")}` : `${paragraph("We received a request to reset your password. The reset token expires in 1 hour.")}${sectionLabel("Reset token")}${detailBox(args.token, true)}`,
|
|
2543
2620
|
footer: "If you didn't request a password reset, you can safely ignore this email."
|
|
2544
2621
|
})
|
|
2545
2622
|
};
|
|
@@ -2572,6 +2649,36 @@ var AuthController = class {
|
|
|
2572
2649
|
} = user;
|
|
2573
2650
|
return safeUser;
|
|
2574
2651
|
}
|
|
2652
|
+
hasField(name) {
|
|
2653
|
+
return (this.collection.fields || []).some((field) => field.name === name);
|
|
2654
|
+
}
|
|
2655
|
+
async buildPendingInviteData(email, extraFields = {}) {
|
|
2656
|
+
const {
|
|
2657
|
+
id: _id,
|
|
2658
|
+
password: _password,
|
|
2659
|
+
email: _email,
|
|
2660
|
+
...safeExtraFields
|
|
2661
|
+
} = extraFields;
|
|
2662
|
+
const data = {
|
|
2663
|
+
...safeExtraFields,
|
|
2664
|
+
email,
|
|
2665
|
+
password: await hashPassword(randomBytes2(32).toString("hex"))
|
|
2666
|
+
};
|
|
2667
|
+
if (this.hasField("status")) {
|
|
2668
|
+
data.status = "pending";
|
|
2669
|
+
}
|
|
2670
|
+
return data;
|
|
2671
|
+
}
|
|
2672
|
+
buildAcceptedInviteData(hashedPassword, extraFields) {
|
|
2673
|
+
const data = {
|
|
2674
|
+
...extraFields,
|
|
2675
|
+
password: hashedPassword
|
|
2676
|
+
};
|
|
2677
|
+
if (this.hasField("status")) {
|
|
2678
|
+
data.status = "active";
|
|
2679
|
+
}
|
|
2680
|
+
return data;
|
|
2681
|
+
}
|
|
2575
2682
|
clearLockoutState(c, userId) {
|
|
2576
2683
|
const db = c.get("config").db;
|
|
2577
2684
|
if (!db) return Promise.resolve(null);
|
|
@@ -2706,6 +2813,12 @@ var AuthController = class {
|
|
|
2706
2813
|
401
|
|
2707
2814
|
);
|
|
2708
2815
|
}
|
|
2816
|
+
if (user.status === "pending") {
|
|
2817
|
+
return c.json(
|
|
2818
|
+
{ error: true, message: "This invitation has not been accepted yet." },
|
|
2819
|
+
403
|
|
2820
|
+
);
|
|
2821
|
+
}
|
|
2709
2822
|
const lockedUntilMs = getLockedUntilMs(user.lockedUntil);
|
|
2710
2823
|
if (lockedUntilMs !== null && lockedUntilMs > Date.now()) {
|
|
2711
2824
|
const retryAfterSeconds = Math.max(
|
|
@@ -2970,6 +3083,7 @@ var AuthController = class {
|
|
|
2970
3083
|
// ---------------------------------------------------------------------------
|
|
2971
3084
|
// POST /invite
|
|
2972
3085
|
// Requires auth. Issues a signed invite token and emails it to the invitee.
|
|
3086
|
+
// If inviteUrl is provided, the email uses a clickable acceptance URL.
|
|
2973
3087
|
// ---------------------------------------------------------------------------
|
|
2974
3088
|
async invite(c) {
|
|
2975
3089
|
const config = c.get("config");
|
|
@@ -2983,17 +3097,32 @@ var AuthController = class {
|
|
|
2983
3097
|
if (!body?.email) {
|
|
2984
3098
|
return c.json({ error: true, message: "email is required." }, 400);
|
|
2985
3099
|
}
|
|
3100
|
+
const inviteData = body?.data && typeof body.data === "object" && !Array.isArray(body.data) ? body.data : {};
|
|
2986
3101
|
const existing = await db.find({
|
|
2987
3102
|
collection: this.collection.slug,
|
|
2988
3103
|
where: { email: body.email },
|
|
2989
3104
|
limit: 1
|
|
2990
3105
|
});
|
|
2991
|
-
|
|
3106
|
+
const existingUser = existing.docs[0];
|
|
3107
|
+
const existingIsPending = existingUser?.status === "pending";
|
|
3108
|
+
if (existingUser && !existingIsPending) {
|
|
2992
3109
|
return c.json(
|
|
2993
3110
|
{ error: true, message: "An account with that email already exists." },
|
|
2994
3111
|
409
|
|
2995
3112
|
);
|
|
2996
3113
|
}
|
|
3114
|
+
if (!existingUser) {
|
|
3115
|
+
await db.create({
|
|
3116
|
+
collection: this.collection.slug,
|
|
3117
|
+
data: await this.buildPendingInviteData(body.email, inviteData)
|
|
3118
|
+
});
|
|
3119
|
+
} else if (Object.keys(inviteData).length > 0) {
|
|
3120
|
+
await db.update({
|
|
3121
|
+
collection: this.collection.slug,
|
|
3122
|
+
id: String(existingUser.id),
|
|
3123
|
+
data: await this.buildPendingInviteData(body.email, inviteData)
|
|
3124
|
+
});
|
|
3125
|
+
}
|
|
2997
3126
|
const inviteToken = await signCollectionToken(
|
|
2998
3127
|
{
|
|
2999
3128
|
sub: body.email,
|
|
@@ -3003,10 +3132,13 @@ var AuthController = class {
|
|
|
3003
3132
|
},
|
|
3004
3133
|
"7d"
|
|
3005
3134
|
);
|
|
3135
|
+
const inviteUrl = body?.inviteUrl;
|
|
3136
|
+
const url = inviteUrl ? `${inviteUrl}${inviteUrl.includes("?") ? "&" : "?"}inviteToken=${encodeURIComponent(inviteToken)}` : void 0;
|
|
3006
3137
|
try {
|
|
3007
3138
|
const { subject, html } = buildInviteEmail(config, {
|
|
3008
3139
|
token: inviteToken,
|
|
3009
|
-
invitedByEmail: requestUser.email
|
|
3140
|
+
invitedByEmail: requestUser.email,
|
|
3141
|
+
url
|
|
3010
3142
|
});
|
|
3011
3143
|
await sendEmail(config, { to: body.email, subject, html });
|
|
3012
3144
|
} catch (err) {
|
|
@@ -3016,7 +3148,12 @@ var AuthController = class {
|
|
|
3016
3148
|
email: body.email
|
|
3017
3149
|
});
|
|
3018
3150
|
}
|
|
3019
|
-
return c.json({
|
|
3151
|
+
return c.json({
|
|
3152
|
+
success: true,
|
|
3153
|
+
message: `Invite sent to ${body.email}.`,
|
|
3154
|
+
token: inviteToken,
|
|
3155
|
+
inviteUrl: url
|
|
3156
|
+
});
|
|
3020
3157
|
}
|
|
3021
3158
|
// ---------------------------------------------------------------------------
|
|
3022
3159
|
// POST /accept-invite
|
|
@@ -3055,7 +3192,9 @@ var AuthController = class {
|
|
|
3055
3192
|
where: { email: inviteeEmail },
|
|
3056
3193
|
limit: 1
|
|
3057
3194
|
});
|
|
3058
|
-
|
|
3195
|
+
const existingUser = existing.docs[0];
|
|
3196
|
+
const existingIsPending = existingUser?.status === "pending";
|
|
3197
|
+
if (existingUser && !existingIsPending) {
|
|
3059
3198
|
return c.json(
|
|
3060
3199
|
{ error: true, message: "An account with that email already exists." },
|
|
3061
3200
|
409
|
|
@@ -3063,9 +3202,17 @@ var AuthController = class {
|
|
|
3063
3202
|
}
|
|
3064
3203
|
const { token: _t, password: _p, ...extraFields } = body;
|
|
3065
3204
|
const hashedPassword = await hashPassword(body.password);
|
|
3066
|
-
const user = await db.
|
|
3205
|
+
const user = existingUser ? await db.update({
|
|
3206
|
+
collection: this.collection.slug,
|
|
3207
|
+
id: String(existingUser.id),
|
|
3208
|
+
data: this.buildAcceptedInviteData(hashedPassword, extraFields)
|
|
3209
|
+
}) : await db.create({
|
|
3067
3210
|
collection: this.collection.slug,
|
|
3068
|
-
data: {
|
|
3211
|
+
data: {
|
|
3212
|
+
...extraFields,
|
|
3213
|
+
email: inviteeEmail,
|
|
3214
|
+
...this.buildAcceptedInviteData(hashedPassword, {})
|
|
3215
|
+
}
|
|
3069
3216
|
});
|
|
3070
3217
|
const sessionToken = await issueAuthSessionToken({
|
|
3071
3218
|
config,
|
|
@@ -3091,7 +3238,7 @@ var AuthController = class {
|
|
|
3091
3238
|
};
|
|
3092
3239
|
|
|
3093
3240
|
// src/controllers/admin-auth.controller.ts
|
|
3094
|
-
import { randomBytes as
|
|
3241
|
+
import { randomBytes as randomBytes3 } from "crypto";
|
|
3095
3242
|
import { TextEncoder } from "util";
|
|
3096
3243
|
import {
|
|
3097
3244
|
SignJWT,
|
|
@@ -3305,7 +3452,7 @@ var AdminAuthController = class {
|
|
|
3305
3452
|
access.roles,
|
|
3306
3453
|
access.data
|
|
3307
3454
|
),
|
|
3308
|
-
password: await hashPassword(
|
|
3455
|
+
password: await hashPassword(randomBytes3(32).toString("hex"))
|
|
3309
3456
|
}
|
|
3310
3457
|
});
|
|
3311
3458
|
} else if (user) {
|
|
@@ -3391,7 +3538,7 @@ var AdminAuthController = class {
|
|
|
3391
3538
|
}
|
|
3392
3539
|
async buildOidcStartUrl(provider, returnTo, siteId, origin) {
|
|
3393
3540
|
const discovery = await this.getOidcDiscovery(provider);
|
|
3394
|
-
const nonce =
|
|
3541
|
+
const nonce = randomBytes3(16).toString("hex");
|
|
3395
3542
|
const state = await this.signState({
|
|
3396
3543
|
providerId: provider.id,
|
|
3397
3544
|
returnTo,
|
|
@@ -3994,6 +4141,7 @@ function getSwaggerHtml(specUrl) {
|
|
|
3994
4141
|
}
|
|
3995
4142
|
|
|
3996
4143
|
// src/router.ts
|
|
4144
|
+
var SERIALIZED_ADMIN_HOOK_PREFIX = "__dyrected_fn__:";
|
|
3997
4145
|
function accessGate(config, target, action) {
|
|
3998
4146
|
return async (c, next) => {
|
|
3999
4147
|
const user = c.get("user");
|
|
@@ -4020,7 +4168,7 @@ function serializeFieldForApi(f) {
|
|
|
4020
4168
|
if (serialized.admin?.hooks) {
|
|
4021
4169
|
const hooks = { ...serialized.admin.hooks };
|
|
4022
4170
|
if (typeof hooks.onChange === "function") {
|
|
4023
|
-
hooks.onChange = hooks.onChange.toString()
|
|
4171
|
+
hooks.onChange = `${SERIALIZED_ADMIN_HOOK_PREFIX}${hooks.onChange.toString()}`;
|
|
4024
4172
|
}
|
|
4025
4173
|
if (typeof hooks.options === "function") {
|
|
4026
4174
|
hooks.options = hooks.options.toString();
|
|
@@ -4054,6 +4202,10 @@ function registerRoutes(app, config) {
|
|
|
4054
4202
|
app.get("/api/schemas", optionalAuth(config), async (c) => {
|
|
4055
4203
|
const siteId = c.req.header("X-Site-Id");
|
|
4056
4204
|
const requestConfig = siteId && config.onSchemaFetch ? mergeDynamicConfig(config, await config.onSchemaFetch(siteId)) : config;
|
|
4205
|
+
assertValidDeclarativeHooksInConfig(requestConfig, "/api/schemas");
|
|
4206
|
+
assertValidDeclarativeAccessInConfig(requestConfig, "/api/schemas");
|
|
4207
|
+
assertValidAdminConditionsInConfig(requestConfig, "/api/schemas");
|
|
4208
|
+
assertValidPreviewUrlsInConfig(requestConfig, "/api/schemas");
|
|
4057
4209
|
const collections = [...requestConfig.collections];
|
|
4058
4210
|
const globals = [...requestConfig.globals];
|
|
4059
4211
|
const user = c.get("user");
|
|
@@ -4168,7 +4320,18 @@ function registerRoutes(app, config) {
|
|
|
4168
4320
|
globals: filteredGlobals,
|
|
4169
4321
|
admin: requestConfig.admin || {},
|
|
4170
4322
|
adminAuth: getPublicAdminAuthConfig(requestConfig.adminAuth, collections),
|
|
4171
|
-
hasStorage: !!requestConfig.storage
|
|
4323
|
+
hasStorage: !!requestConfig.storage,
|
|
4324
|
+
configDiagnostics: collectConfigDiagnostics(requestConfig),
|
|
4325
|
+
adminHealth: {
|
|
4326
|
+
emailConfigured: !!requestConfig.email,
|
|
4327
|
+
secureAuthSecretConfigured: !!process.env.DYRECTED_JWT_SECRET,
|
|
4328
|
+
authCollectionConfigured: requestConfig.collections.some(
|
|
4329
|
+
(collection) => !!collection.auth
|
|
4330
|
+
),
|
|
4331
|
+
uploadCollectionConfigured: requestConfig.collections.some(
|
|
4332
|
+
(collection) => !!collection.upload
|
|
4333
|
+
)
|
|
4334
|
+
}
|
|
4172
4335
|
});
|
|
4173
4336
|
});
|
|
4174
4337
|
app.get(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DatabaseAdapter, DyrectedConfig } from '../types/index.js';
|
|
2
|
+
export interface AuditLogArgs {
|
|
3
|
+
operation: 'create' | 'update' | 'delete';
|
|
4
|
+
collection: string;
|
|
5
|
+
documentId?: string;
|
|
6
|
+
user?: {
|
|
7
|
+
id: string;
|
|
8
|
+
collection: string;
|
|
9
|
+
email?: string;
|
|
10
|
+
};
|
|
11
|
+
/** Full state before the operation (null for create). */
|
|
12
|
+
before?: any;
|
|
13
|
+
/** Full state after the operation (null for delete). */
|
|
14
|
+
after?: any;
|
|
15
|
+
}
|
|
16
|
+
export declare class AuditService {
|
|
17
|
+
/**
|
|
18
|
+
* Writes a single entry to the __audit collection.
|
|
19
|
+
* Called without await — runs asynchronously and never blocks the primary operation.
|
|
20
|
+
*/
|
|
21
|
+
static log(db: DatabaseAdapter, args: AuditLogArgs, config?: DyrectedConfig): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=audit.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.service.d.ts","sourceRoot":"","sources":["../../src/services/audit.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGzE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,yDAAyD;IACzD,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,wDAAwD;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,qBAAa,YAAY;IACvB;;;OAGG;WACU,GAAG,CACd,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC;CA8BjB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getConfigLogger, getObservabilityRuntime } from '../observability.js';
|
|
2
|
+
export class AuditService {
|
|
3
|
+
/**
|
|
4
|
+
* Writes a single entry to the __audit collection.
|
|
5
|
+
* Called without await — runs asynchronously and never blocks the primary operation.
|
|
6
|
+
*/
|
|
7
|
+
static async log(db, args, config) {
|
|
8
|
+
try {
|
|
9
|
+
await db.create({
|
|
10
|
+
collection: '__audit',
|
|
11
|
+
data: {
|
|
12
|
+
collection: args.collection,
|
|
13
|
+
documentId: args.documentId ?? null,
|
|
14
|
+
operation: args.operation,
|
|
15
|
+
user: args.user?.id ?? null,
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
changes: JSON.stringify({
|
|
18
|
+
before: args.before ?? null,
|
|
19
|
+
after: args.after ?? null,
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
getObservabilityRuntime(config)?.recordAuditWriteFailure({
|
|
26
|
+
collection: args.collection,
|
|
27
|
+
operation: args.operation,
|
|
28
|
+
});
|
|
29
|
+
getConfigLogger(config, 'audit').error({
|
|
30
|
+
err,
|
|
31
|
+
msg: 'Failed to write audit log',
|
|
32
|
+
collection: args.collection,
|
|
33
|
+
operation: args.operation,
|
|
34
|
+
documentId: args.documentId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=audit.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.service.js","sourceRoot":"","sources":["../../src/services/audit.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAa/E,MAAM,OAAO,YAAY;IACvB;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,CACd,EAAmB,EACnB,IAAkB,EAClB,MAAuB;QAEvB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC;gBACd,UAAU,EAAE,SAAS;gBACrB,IAAI,EAAE;oBACJ,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;oBACnC,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI;oBAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;wBACtB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;wBAC3B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;qBAC1B,CAAC;iBACH;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,uBAAuB,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;gBACvD,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;YACH,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC;gBACrC,GAAG;gBACH,GAAG,EAAE,2BAA2B;gBAChC,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Field } from '../types/index.js';
|
|
2
|
+
export declare class DefaultsService {
|
|
3
|
+
/**
|
|
4
|
+
* Recursively apply default values to a data object based on field definitions.
|
|
5
|
+
*/
|
|
6
|
+
static apply(fields: Field[], data?: any): any;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=defaults.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.service.d.ts","sourceRoot":"","sources":["../../src/services/defaults.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,GAAE,GAAQ,GAAG,GAAG;CA6CnD"}
|