@tstdl/base 0.93.181 → 0.93.183
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/api/server/api-request-token.provider.js +1 -1
- package/api/server/gateway.js +8 -3
- package/authentication/authentication.api.d.ts +13 -40
- package/authentication/authentication.api.js +5 -14
- package/authentication/client/authentication.service.d.ts +6 -14
- package/authentication/client/authentication.service.js +22 -4
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -4
- package/authentication/models/index.d.ts +1 -0
- package/authentication/models/index.js +1 -0
- package/authentication/models/totp-results.model.d.ts +11 -0
- package/authentication/models/totp-results.model.js +37 -0
- package/authentication/server/authentication.api-controller.d.ts +3 -3
- package/authentication/server/authentication.api-controller.js +31 -4
- package/authentication/server/authentication.service.d.ts +5 -14
- package/authentication/server/authentication.service.js +6 -4
- package/core.d.ts +0 -5
- package/core.js +0 -8
- package/document-management/api/document-management.api.d.ts +2 -2
- package/document-management/service-models/document.service-model.d.ts +1 -1
- package/examples/config.d.ts +25 -0
- package/examples/config.js +26 -0
- package/notification/server/module.d.ts +1 -1
- package/notification/server/module.js +1 -1
- package/package.json +5 -5
- package/signals/api.d.ts +5 -1
- package/signals/api.js +3 -1
- package/signals/implementation/api.d.ts +13 -5
- package/signals/implementation/api.js +7 -1
- package/signals/implementation/asserts.d.ts +2 -2
- package/signals/implementation/asserts.js +3 -3
- package/signals/implementation/computed.d.ts +7 -34
- package/signals/implementation/computed.js +14 -83
- package/signals/implementation/configure.js +6 -2
- package/signals/implementation/effect.d.ts +65 -46
- package/signals/implementation/effect.js +97 -62
- package/signals/implementation/index.d.ts +2 -4
- package/signals/implementation/index.js +2 -4
- package/signals/implementation/linked_signal.d.ts +36 -0
- package/signals/implementation/linked_signal.js +34 -0
- package/signals/implementation/primitive/computed.d.ts +55 -0
- package/signals/implementation/primitive/computed.js +107 -0
- package/signals/implementation/primitive/effect.d.ts +26 -0
- package/signals/implementation/primitive/effect.js +31 -0
- package/signals/implementation/{equality.d.ts → primitive/equality.d.ts} +1 -1
- package/signals/implementation/{equality.js → primitive/equality.js} +1 -1
- package/signals/implementation/primitive/errors.d.ts +10 -0
- package/signals/implementation/{errors.js → primitive/errors.js} +3 -4
- package/signals/implementation/primitive/formatter.d.ts +19 -0
- package/signals/implementation/primitive/formatter.js +136 -0
- package/signals/implementation/{graph.d.ts → primitive/graph.d.ts} +68 -36
- package/signals/implementation/primitive/graph.js +386 -0
- package/signals/implementation/primitive/linked_signal.d.ts +46 -0
- package/signals/implementation/primitive/linked_signal.js +110 -0
- package/signals/implementation/primitive/signal.d.ts +31 -0
- package/signals/implementation/primitive/signal.js +80 -0
- package/signals/implementation/primitive/untracked.d.ts +12 -0
- package/signals/implementation/primitive/untracked.js +23 -0
- package/signals/implementation/{watch.d.ts → primitive/watch.d.ts} +1 -2
- package/signals/implementation/{watch.js → primitive/watch.js} +22 -16
- package/signals/implementation/resource/api.d.ts +275 -0
- package/signals/implementation/resource/api.js +26 -0
- package/signals/implementation/resource/debounce.d.ts +13 -0
- package/signals/implementation/resource/debounce.js +113 -0
- package/signals/implementation/resource/from_snapshots.d.ts +16 -0
- package/signals/implementation/resource/from_snapshots.js +44 -0
- package/signals/implementation/resource/index.d.ts +11 -0
- package/signals/implementation/resource/index.js +11 -0
- package/signals/implementation/resource/resource.d.ts +110 -0
- package/signals/implementation/resource/resource.js +402 -0
- package/signals/implementation/root_effect_scheduler.d.ts +50 -0
- package/signals/implementation/root_effect_scheduler.js +66 -0
- package/signals/implementation/signal.d.ts +42 -18
- package/signals/implementation/signal.js +29 -49
- package/signals/implementation/to-observable.d.ts +12 -5
- package/signals/implementation/to-observable.js +12 -2
- package/signals/implementation/to-signal.d.ts +9 -18
- package/signals/implementation/to-signal.js +46 -13
- package/signals/implementation/untracked.d.ts +1 -1
- package/signals/implementation/untracked.js +3 -11
- package/signals/operators/debounce.d.ts +8 -0
- package/signals/operators/debounce.js +19 -0
- package/signals/operators/derive-async.js +43 -15
- package/signals/operators/index.d.ts +2 -0
- package/signals/operators/index.js +2 -0
- package/signals/operators/throttle.d.ts +8 -0
- package/signals/operators/throttle.js +31 -0
- package/ai/genkit/tests/multi-region.test.d.ts +0 -2
- package/ai/genkit/tests/multi-region.test.js +0 -179
- package/ai/genkit/tests/token-limit-fallback.test.d.ts +0 -2
- package/ai/genkit/tests/token-limit-fallback.test.js +0 -209
- package/ai/prompts/tests/prompt-builder.test.d.ts +0 -1
- package/ai/prompts/tests/prompt-builder.test.js +0 -22
- package/ai/tests/instructions-formatter.test.d.ts +0 -1
- package/ai/tests/instructions-formatter.test.js +0 -116
- package/ai/tests/steering.test.d.ts +0 -1
- package/ai/tests/steering.test.js +0 -37
- package/api/client/tests/api-client.test.d.ts +0 -1
- package/api/client/tests/api-client.test.js +0 -194
- package/api/server/tests/csrf.middleware.test.d.ts +0 -1
- package/api/server/tests/csrf.middleware.test.js +0 -91
- package/authentication/tests/authentication-password-requirements.validator.test.d.ts +0 -1
- package/authentication/tests/authentication-password-requirements.validator.test.js +0 -29
- package/authentication/tests/authentication.api-controller.test.d.ts +0 -1
- package/authentication/tests/authentication.api-controller.test.js +0 -156
- package/authentication/tests/authentication.api-request-token.provider.test.d.ts +0 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +0 -48
- package/authentication/tests/authentication.client-error-handling.test.d.ts +0 -1
- package/authentication/tests/authentication.client-error-handling.test.js +0 -123
- package/authentication/tests/authentication.client-middleware.test.d.ts +0 -1
- package/authentication/tests/authentication.client-middleware.test.js +0 -118
- package/authentication/tests/authentication.client-service-methods.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-methods.test.js +0 -177
- package/authentication/tests/authentication.client-service-refresh.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-refresh.test.js +0 -153
- package/authentication/tests/authentication.client-service.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service.test.js +0 -76
- package/authentication/tests/authentication.refresh-busy-loop.test.d.ts +0 -1
- package/authentication/tests/authentication.refresh-busy-loop.test.js +0 -84
- package/authentication/tests/authentication.service.test.d.ts +0 -1
- package/authentication/tests/authentication.service.test.js +0 -167
- package/authentication/tests/authentication.test-ancillary-service.d.ts +0 -9
- package/authentication/tests/authentication.test-ancillary-service.js +0 -27
- package/authentication/tests/brute-force-protection.test.d.ts +0 -1
- package/authentication/tests/brute-force-protection.test.js +0 -211
- package/authentication/tests/helper.test.d.ts +0 -1
- package/authentication/tests/helper.test.js +0 -122
- package/authentication/tests/password-requirements.error.test.d.ts +0 -1
- package/authentication/tests/password-requirements.error.test.js +0 -14
- package/authentication/tests/remember.api.test.d.ts +0 -1
- package/authentication/tests/remember.api.test.js +0 -117
- package/authentication/tests/remember.service.test.d.ts +0 -1
- package/authentication/tests/remember.service.test.js +0 -83
- package/authentication/tests/subject.service.test.d.ts +0 -1
- package/authentication/tests/subject.service.test.js +0 -140
- package/authentication/tests/suspended-subject.test.d.ts +0 -1
- package/authentication/tests/suspended-subject.test.js +0 -120
- package/authentication/tests/totp.enrollment.test.d.ts +0 -1
- package/authentication/tests/totp.enrollment.test.js +0 -123
- package/authentication/tests/totp.login.test.d.ts +0 -1
- package/authentication/tests/totp.login.test.js +0 -213
- package/authentication/tests/totp.recovery-codes.test.d.ts +0 -1
- package/authentication/tests/totp.recovery-codes.test.js +0 -97
- package/authentication/tests/totp.status.test.d.ts +0 -1
- package/authentication/tests/totp.status.test.js +0 -72
- package/cancellation/tests/coverage.test.d.ts +0 -1
- package/cancellation/tests/coverage.test.js +0 -49
- package/cancellation/tests/leak.test.d.ts +0 -1
- package/cancellation/tests/leak.test.js +0 -35
- package/cancellation/tests/token.test.d.ts +0 -1
- package/cancellation/tests/token.test.js +0 -136
- package/circuit-breaker/tests/circuit-breaker.test.d.ts +0 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +0 -116
- package/cryptography/tests/cryptography.test.d.ts +0 -1
- package/cryptography/tests/cryptography.test.js +0 -175
- package/cryptography/tests/jwt.test.d.ts +0 -1
- package/cryptography/tests/jwt.test.js +0 -54
- package/cryptography/tests/modern.test.d.ts +0 -1
- package/cryptography/tests/modern.test.js +0 -105
- package/cryptography/tests/module.test.d.ts +0 -1
- package/cryptography/tests/module.test.js +0 -100
- package/cryptography/tests/totp.test.d.ts +0 -1
- package/cryptography/tests/totp.test.js +0 -108
- package/document-management/tests/ai-config-hierarchy.test.d.ts +0 -1
- package/document-management/tests/ai-config-hierarchy.test.js +0 -59
- package/document-management/tests/ai-config-integration.test.d.ts +0 -1
- package/document-management/tests/ai-config-integration.test.js +0 -125
- package/document-management/tests/ai-config-merge.test.d.ts +0 -1
- package/document-management/tests/ai-config-merge.test.js +0 -46
- package/document-management/tests/document-management-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-management-ai-overrides.test.js +0 -63
- package/document-management/tests/document-management-core.test.d.ts +0 -1
- package/document-management/tests/document-management-core.test.js +0 -157
- package/document-management/tests/document-management.api.test.d.ts +0 -1
- package/document-management/tests/document-management.api.test.js +0 -101
- package/document-management/tests/document-statistics.service.test.d.ts +0 -1
- package/document-management/tests/document-statistics.service.test.js +0 -498
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-validation-ai-overrides.test.js +0 -87
- package/document-management/tests/document.service.test.d.ts +0 -1
- package/document-management/tests/document.service.test.js +0 -143
- package/document-management/tests/enum-helpers.test.d.ts +0 -1
- package/document-management/tests/enum-helpers.test.js +0 -452
- package/document-management/tests/helper.d.ts +0 -24
- package/document-management/tests/helper.js +0 -39
- package/errors/tests/format.test.d.ts +0 -1
- package/errors/tests/format.test.js +0 -84
- package/http/tests/server-timing.test.d.ts +0 -1
- package/http/tests/server-timing.test.js +0 -42
- package/injector/tests/advanced.test.d.ts +0 -1
- package/injector/tests/advanced.test.js +0 -116
- package/injector/tests/async-init.test.d.ts +0 -1
- package/injector/tests/async-init.test.js +0 -77
- package/injector/tests/basic.test.d.ts +0 -1
- package/injector/tests/basic.test.js +0 -114
- package/injector/tests/hierarchical.test.d.ts +0 -1
- package/injector/tests/hierarchical.test.js +0 -59
- package/injector/tests/leak.test.d.ts +0 -1
- package/injector/tests/leak.test.js +0 -45
- package/injector/tests/lifecycles.test.d.ts +0 -1
- package/injector/tests/lifecycles.test.js +0 -109
- package/logger/tests/pretty-print.test.d.ts +0 -1
- package/logger/tests/pretty-print.test.js +0 -60
- package/notification/tests/notification-api.test.d.ts +0 -1
- package/notification/tests/notification-api.test.js +0 -124
- package/notification/tests/notification-client.test.d.ts +0 -1
- package/notification/tests/notification-client.test.js +0 -101
- package/notification/tests/notification-flow.test.d.ts +0 -1
- package/notification/tests/notification-flow.test.js +0 -296
- package/notification/tests/notification-sse.service.test.d.ts +0 -1
- package/notification/tests/notification-sse.service.test.js +0 -43
- package/notification/tests/notification-type.service.test.d.ts +0 -1
- package/notification/tests/notification-type.service.test.js +0 -41
- package/object-storage/s3/tests/s3.object-storage.integration.test.d.ts +0 -1
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +0 -303
- package/orm/tests/build-jsonb.test.d.ts +0 -1
- package/orm/tests/build-jsonb.test.js +0 -39
- package/orm/tests/data-types.test.d.ts +0 -1
- package/orm/tests/data-types.test.js +0 -39
- package/orm/tests/database-extension.test.d.ts +0 -1
- package/orm/tests/database-extension.test.js +0 -63
- package/orm/tests/database-migration.test.d.ts +0 -1
- package/orm/tests/database-migration.test.js +0 -83
- package/orm/tests/decorators.test.d.ts +0 -1
- package/orm/tests/decorators.test.js +0 -77
- package/orm/tests/encryption.test.d.ts +0 -1
- package/orm/tests/encryption.test.js +0 -31
- package/orm/tests/query-complex.test.d.ts +0 -1
- package/orm/tests/query-complex.test.js +0 -172
- package/orm/tests/query-converter-complex.test.d.ts +0 -1
- package/orm/tests/query-converter-complex.test.js +0 -131
- package/orm/tests/query-converter.test.d.ts +0 -1
- package/orm/tests/query-converter.test.js +0 -123
- package/orm/tests/repository-advanced.test.d.ts +0 -1
- package/orm/tests/repository-advanced.test.js +0 -189
- package/orm/tests/repository-attributes.test.d.ts +0 -1
- package/orm/tests/repository-attributes.test.js +0 -83
- package/orm/tests/repository-compound-primary-key.test.d.ts +0 -2
- package/orm/tests/repository-compound-primary-key.test.js +0 -226
- package/orm/tests/repository-comprehensive.test.d.ts +0 -1
- package/orm/tests/repository-comprehensive.test.js +0 -162
- package/orm/tests/repository-coverage.test.d.ts +0 -2
- package/orm/tests/repository-coverage.test.js +0 -242
- package/orm/tests/repository-cti-complex.test.d.ts +0 -1
- package/orm/tests/repository-cti-complex.test.js +0 -151
- package/orm/tests/repository-cti-embedded.test.d.ts +0 -1
- package/orm/tests/repository-cti-embedded.test.js +0 -178
- package/orm/tests/repository-cti-extensive.test.d.ts +0 -2
- package/orm/tests/repository-cti-extensive.test.js +0 -279
- package/orm/tests/repository-cti-mapping.test.d.ts +0 -2
- package/orm/tests/repository-cti-mapping.test.js +0 -108
- package/orm/tests/repository-cti-search.test.d.ts +0 -1
- package/orm/tests/repository-cti-search.test.js +0 -141
- package/orm/tests/repository-cti-soft-delete.test.d.ts +0 -2
- package/orm/tests/repository-cti-soft-delete.test.js +0 -103
- package/orm/tests/repository-cti-transactions.test.d.ts +0 -1
- package/orm/tests/repository-cti-transactions.test.js +0 -112
- package/orm/tests/repository-cti-upsert-many.test.d.ts +0 -2
- package/orm/tests/repository-cti-upsert-many.test.js +0 -115
- package/orm/tests/repository-cti.test.d.ts +0 -2
- package/orm/tests/repository-cti.test.js +0 -390
- package/orm/tests/repository-edge-cases.test.d.ts +0 -1
- package/orm/tests/repository-edge-cases.test.js +0 -178
- package/orm/tests/repository-expiration.test.d.ts +0 -2
- package/orm/tests/repository-expiration.test.js +0 -140
- package/orm/tests/repository-extra-coverage.test.d.ts +0 -2
- package/orm/tests/repository-extra-coverage.test.js +0 -402
- package/orm/tests/repository-mapping.test.d.ts +0 -2
- package/orm/tests/repository-mapping.test.js +0 -65
- package/orm/tests/repository-regression.test.d.ts +0 -1
- package/orm/tests/repository-regression.test.js +0 -288
- package/orm/tests/repository-search-coverage.test.d.ts +0 -1
- package/orm/tests/repository-search-coverage.test.js +0 -107
- package/orm/tests/repository-search.test.d.ts +0 -1
- package/orm/tests/repository-search.test.js +0 -105
- package/orm/tests/repository-soft-delete.test.d.ts +0 -1
- package/orm/tests/repository-soft-delete.test.js +0 -118
- package/orm/tests/repository-transactions-nested.test.d.ts +0 -1
- package/orm/tests/repository-transactions-nested.test.js +0 -178
- package/orm/tests/repository-types.test.d.ts +0 -1
- package/orm/tests/repository-types.test.js +0 -184
- package/orm/tests/repository-undelete.test.d.ts +0 -2
- package/orm/tests/repository-undelete.test.js +0 -201
- package/orm/tests/schema-converter.test.d.ts +0 -1
- package/orm/tests/schema-converter.test.js +0 -82
- package/orm/tests/schema-generation.test.d.ts +0 -2
- package/orm/tests/schema-generation.test.js +0 -174
- package/orm/tests/sql-helpers.test.d.ts +0 -1
- package/orm/tests/sql-helpers.test.js +0 -67
- package/orm/tests/transaction-safety.test.d.ts +0 -1
- package/orm/tests/transaction-safety.test.js +0 -81
- package/orm/tests/transactional.test.d.ts +0 -1
- package/orm/tests/transactional.test.js +0 -215
- package/orm/tests/utils.test.d.ts +0 -1
- package/orm/tests/utils.test.js +0 -70
- package/pdf/tests/utils.test.d.ts +0 -1
- package/pdf/tests/utils.test.js +0 -187
- package/process/tests/spawn.test.d.ts +0 -1
- package/process/tests/spawn.test.js +0 -182
- package/rate-limit/tests/postgres-rate-limiter.test.d.ts +0 -1
- package/rate-limit/tests/postgres-rate-limiter.test.js +0 -84
- package/renderer/tests/renderer.test.d.ts +0 -1
- package/renderer/tests/renderer.test.js +0 -88
- package/rpc/tests/rpc.integration.test.d.ts +0 -1
- package/rpc/tests/rpc.integration.test.js +0 -615
- package/signals/implementation/errors.d.ts +0 -2
- package/signals/implementation/graph.js +0 -312
- package/signals/implementation/writable-signal.d.ts +0 -48
- package/signals/implementation/writable-signal.js +0 -32
- package/task-queue/tests/coverage-branch.test.d.ts +0 -1
- package/task-queue/tests/coverage-branch.test.js +0 -395
- package/task-queue/tests/coverage-enhancement.test.d.ts +0 -1
- package/task-queue/tests/coverage-enhancement.test.js +0 -150
- package/task-queue/tests/dag.test.d.ts +0 -1
- package/task-queue/tests/dag.test.js +0 -188
- package/task-queue/tests/dependencies.test.d.ts +0 -1
- package/task-queue/tests/dependencies.test.js +0 -296
- package/task-queue/tests/enqueue-batch.test.d.ts +0 -1
- package/task-queue/tests/enqueue-batch.test.js +0 -125
- package/task-queue/tests/enqueue-item.test.d.ts +0 -1
- package/task-queue/tests/enqueue-item.test.js +0 -12
- package/task-queue/tests/fan-out-spawning.test.d.ts +0 -1
- package/task-queue/tests/fan-out-spawning.test.js +0 -94
- package/task-queue/tests/idempotent-replacement.test.d.ts +0 -1
- package/task-queue/tests/idempotent-replacement.test.js +0 -114
- package/task-queue/tests/missing-idempotent-tasks.test.d.ts +0 -1
- package/task-queue/tests/missing-idempotent-tasks.test.js +0 -39
- package/task-queue/tests/optimization-edge-cases.test.d.ts +0 -1
- package/task-queue/tests/optimization-edge-cases.test.js +0 -124
- package/task-queue/tests/queue-generic.test.d.ts +0 -1
- package/task-queue/tests/queue-generic.test.js +0 -8
- package/task-queue/tests/queue.test.d.ts +0 -1
- package/task-queue/tests/queue.test.js +0 -756
- package/task-queue/tests/shutdown.test.d.ts +0 -1
- package/task-queue/tests/shutdown.test.js +0 -41
- package/task-queue/tests/task-context.test.d.ts +0 -1
- package/task-queue/tests/task-context.test.js +0 -7
- package/task-queue/tests/task-union.test.d.ts +0 -1
- package/task-queue/tests/task-union.test.js +0 -18
- package/task-queue/tests/transactions.test.d.ts +0 -1
- package/task-queue/tests/transactions.test.js +0 -47
- package/task-queue/tests/typing.test.d.ts +0 -1
- package/task-queue/tests/typing.test.js +0 -9
- package/task-queue/tests/worker.test.d.ts +0 -1
- package/task-queue/tests/worker.test.js +0 -258
- package/task-queue/tests/zombie-parent.test.d.ts +0 -1
- package/task-queue/tests/zombie-parent.test.js +0 -45
- package/task-queue/tests/zombie-recovery.test.d.ts +0 -1
- package/task-queue/tests/zombie-recovery.test.js +0 -51
- package/utils/tests/backoff.test.d.ts +0 -1
- package/utils/tests/backoff.test.js +0 -41
- package/utils/tests/retry-with-backoff.test.d.ts +0 -1
- package/utils/tests/retry-with-backoff.test.js +0 -49
|
@@ -19,7 +19,7 @@ export class ApiRequestTokenProvider {
|
|
|
19
19
|
}
|
|
20
20
|
let NoopApiRequestTokenProvider = class NoopApiRequestTokenProvider extends ApiRequestTokenProvider {
|
|
21
21
|
tryGetToken(_requestData) {
|
|
22
|
-
throw new Error('No
|
|
22
|
+
throw new Error('No ApiRequestTokenProvider registered');
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
NoopApiRequestTokenProvider = __decorate([
|
package/api/server/gateway.js
CHANGED
|
@@ -29,7 +29,7 @@ import { toArray } from '../../utils/array/array.js';
|
|
|
29
29
|
import { composeAsyncMiddleware } from '../../utils/middleware.js';
|
|
30
30
|
import { mapObjectValues } from '../../utils/object/object.js';
|
|
31
31
|
import { deferThrow } from '../../utils/throw.js';
|
|
32
|
-
import { isArray, isBlob, isDefined,
|
|
32
|
+
import { isArray, isBlob, isDefined, isNotNull, isNotNullOrUndefined, isNull, isNullOrUndefined, isObject, isReadableStream, isUint8Array, isUndefined } from '../../utils/type-guards.js';
|
|
33
33
|
import { mebibyte } from '../../utils/units.js';
|
|
34
34
|
import { logAndGetErrorResponse } from '../response.js';
|
|
35
35
|
import { normalizedApiDefinition, normalizedApiDefinitionEndpointsEntries } from '../types.js';
|
|
@@ -245,8 +245,13 @@ let ApiGateway = ApiGateway_1 = class ApiGateway {
|
|
|
245
245
|
}
|
|
246
246
|
else {
|
|
247
247
|
const endpointDefinitionResult = context.endpoint.definition.result;
|
|
248
|
-
if (isDevMode() && isDefined(endpointDefinitionResult) &&
|
|
249
|
-
|
|
248
|
+
if (isDevMode() && isDefined(endpointDefinitionResult) && (endpointDefinitionResult != DataStream) && (endpointDefinitionResult != ServerSentEvents)) {
|
|
249
|
+
try {
|
|
250
|
+
Schema.assert(endpointDefinitionResult, result);
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
throw new Error(`Result of endpoint ${context.request.method} ${context.api.resource} (${context.endpoint.implementation.name}) did not match schema.`, { cause: error });
|
|
254
|
+
}
|
|
250
255
|
}
|
|
251
256
|
context.response.body = match(result)
|
|
252
257
|
.when(isUint8Array, (buffer) => ({ buffer }))
|
|
@@ -2,7 +2,7 @@ import { type ApiDefinition, type ApiEndpointsDefinition } from '../api/types.js
|
|
|
2
2
|
import { type ObjectSchema, type ObjectSchemaOrType } from '../schema/index.js';
|
|
3
3
|
import type { SchemaTestable } from '../schema/schema.js';
|
|
4
4
|
import type { Record } from '../types/index.js';
|
|
5
|
-
import { type TokenPayload } from './models/index.js';
|
|
5
|
+
import { TotpEnrollmentInitResult, TotpRecoveryCodesResult, TotpStatusResult, type TokenPayload } from './models/index.js';
|
|
6
6
|
import { PasswordCheckResult } from './models/password-check-result.model.js';
|
|
7
7
|
/**
|
|
8
8
|
* Can be provided in {@link ApiEndpointDefinition} data property to signal that the request does not need a valid token.
|
|
@@ -83,10 +83,7 @@ export declare const authenticationApiDefinition: {
|
|
|
83
83
|
initEnrollTotp: {
|
|
84
84
|
resource: string;
|
|
85
85
|
method: "POST";
|
|
86
|
-
result:
|
|
87
|
-
secret: string;
|
|
88
|
-
uri: string;
|
|
89
|
-
}>;
|
|
86
|
+
result: typeof TotpEnrollmentInitResult;
|
|
90
87
|
credentials: true;
|
|
91
88
|
};
|
|
92
89
|
completeEnrollTotp: {
|
|
@@ -95,9 +92,7 @@ export declare const authenticationApiDefinition: {
|
|
|
95
92
|
parameters: ObjectSchema<{
|
|
96
93
|
token: string;
|
|
97
94
|
}>;
|
|
98
|
-
result:
|
|
99
|
-
recoveryCodes: string[];
|
|
100
|
-
}>;
|
|
95
|
+
result: typeof TotpRecoveryCodesResult;
|
|
101
96
|
credentials: true;
|
|
102
97
|
};
|
|
103
98
|
disableTotp: {
|
|
@@ -125,17 +120,13 @@ export declare const authenticationApiDefinition: {
|
|
|
125
120
|
token: string;
|
|
126
121
|
invalidateOtherSessions?: boolean | undefined;
|
|
127
122
|
}>;
|
|
128
|
-
result:
|
|
129
|
-
recoveryCodes: string[];
|
|
130
|
-
}>;
|
|
123
|
+
result: typeof TotpRecoveryCodesResult;
|
|
131
124
|
credentials: true;
|
|
132
125
|
};
|
|
133
126
|
getTotpStatus: {
|
|
134
127
|
resource: string;
|
|
135
128
|
method: "GET";
|
|
136
|
-
result:
|
|
137
|
-
active: boolean;
|
|
138
|
-
}>;
|
|
129
|
+
result: typeof TotpStatusResult;
|
|
139
130
|
credentials: true;
|
|
140
131
|
};
|
|
141
132
|
refresh: {
|
|
@@ -322,10 +313,7 @@ export declare function getAuthenticationApiDefinition<AdditionalTokenPayload ex
|
|
|
322
313
|
initEnrollTotp: {
|
|
323
314
|
resource: string;
|
|
324
315
|
method: "POST";
|
|
325
|
-
result:
|
|
326
|
-
secret: string;
|
|
327
|
-
uri: string;
|
|
328
|
-
}>;
|
|
316
|
+
result: typeof TotpEnrollmentInitResult;
|
|
329
317
|
credentials: true;
|
|
330
318
|
};
|
|
331
319
|
completeEnrollTotp: {
|
|
@@ -334,9 +322,7 @@ export declare function getAuthenticationApiDefinition<AdditionalTokenPayload ex
|
|
|
334
322
|
parameters: ObjectSchema<{
|
|
335
323
|
token: string;
|
|
336
324
|
}>;
|
|
337
|
-
result:
|
|
338
|
-
recoveryCodes: string[];
|
|
339
|
-
}>;
|
|
325
|
+
result: typeof TotpRecoveryCodesResult;
|
|
340
326
|
credentials: true;
|
|
341
327
|
};
|
|
342
328
|
disableTotp: {
|
|
@@ -364,17 +350,13 @@ export declare function getAuthenticationApiDefinition<AdditionalTokenPayload ex
|
|
|
364
350
|
token: string;
|
|
365
351
|
invalidateOtherSessions?: boolean | undefined;
|
|
366
352
|
}>;
|
|
367
|
-
result:
|
|
368
|
-
recoveryCodes: string[];
|
|
369
|
-
}>;
|
|
353
|
+
result: typeof TotpRecoveryCodesResult;
|
|
370
354
|
credentials: true;
|
|
371
355
|
};
|
|
372
356
|
getTotpStatus: {
|
|
373
357
|
resource: string;
|
|
374
358
|
method: "GET";
|
|
375
|
-
result:
|
|
376
|
-
active: boolean;
|
|
377
|
-
}>;
|
|
359
|
+
result: typeof TotpStatusResult;
|
|
378
360
|
credentials: true;
|
|
379
361
|
};
|
|
380
362
|
refresh: {
|
|
@@ -556,10 +538,7 @@ export declare function getAuthenticationApiEndpointsDefinition<AdditionalTokenP
|
|
|
556
538
|
initEnrollTotp: {
|
|
557
539
|
resource: string;
|
|
558
540
|
method: "POST";
|
|
559
|
-
result:
|
|
560
|
-
secret: string;
|
|
561
|
-
uri: string;
|
|
562
|
-
}>;
|
|
541
|
+
result: typeof TotpEnrollmentInitResult;
|
|
563
542
|
credentials: true;
|
|
564
543
|
};
|
|
565
544
|
completeEnrollTotp: {
|
|
@@ -568,9 +547,7 @@ export declare function getAuthenticationApiEndpointsDefinition<AdditionalTokenP
|
|
|
568
547
|
parameters: ObjectSchema<{
|
|
569
548
|
token: string;
|
|
570
549
|
}>;
|
|
571
|
-
result:
|
|
572
|
-
recoveryCodes: string[];
|
|
573
|
-
}>;
|
|
550
|
+
result: typeof TotpRecoveryCodesResult;
|
|
574
551
|
credentials: true;
|
|
575
552
|
};
|
|
576
553
|
disableTotp: {
|
|
@@ -598,17 +575,13 @@ export declare function getAuthenticationApiEndpointsDefinition<AdditionalTokenP
|
|
|
598
575
|
token: string;
|
|
599
576
|
invalidateOtherSessions?: boolean | undefined;
|
|
600
577
|
}>;
|
|
601
|
-
result:
|
|
602
|
-
recoveryCodes: string[];
|
|
603
|
-
}>;
|
|
578
|
+
result: typeof TotpRecoveryCodesResult;
|
|
604
579
|
credentials: true;
|
|
605
580
|
};
|
|
606
581
|
getTotpStatus: {
|
|
607
582
|
resource: string;
|
|
608
583
|
method: "GET";
|
|
609
|
-
result:
|
|
610
|
-
active: boolean;
|
|
611
|
-
}>;
|
|
584
|
+
result: typeof TotpStatusResult;
|
|
612
585
|
credentials: true;
|
|
613
586
|
};
|
|
614
587
|
refresh: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineApi } from '../api/types.js';
|
|
2
2
|
import { array, assign, boolean, defaulted, emptyObjectSchema, explicitObject, literal, never, number, object, optional, pick, string, union } from '../schema/index.js';
|
|
3
|
-
import { AuthenticationSession } from './models/index.js';
|
|
3
|
+
import { AuthenticationSession, TotpEnrollmentInitResult, TotpRecoveryCodesResult, TotpStatusResult } from './models/index.js';
|
|
4
4
|
import { PasswordCheckResult } from './models/password-check-result.model.js';
|
|
5
5
|
import { TokenPayloadBase } from './models/token-payload-base.model.js';
|
|
6
6
|
/**
|
|
@@ -100,10 +100,7 @@ export function getAuthenticationApiEndpointsDefinition(additionalTokenPayloadSc
|
|
|
100
100
|
initEnrollTotp: {
|
|
101
101
|
resource: 'totp/enroll/init',
|
|
102
102
|
method: 'POST',
|
|
103
|
-
result:
|
|
104
|
-
secret: string(),
|
|
105
|
-
uri: string(),
|
|
106
|
-
}),
|
|
103
|
+
result: TotpEnrollmentInitResult,
|
|
107
104
|
credentials: true,
|
|
108
105
|
},
|
|
109
106
|
completeEnrollTotp: {
|
|
@@ -112,9 +109,7 @@ export function getAuthenticationApiEndpointsDefinition(additionalTokenPayloadSc
|
|
|
112
109
|
parameters: object({
|
|
113
110
|
token: string(),
|
|
114
111
|
}),
|
|
115
|
-
result:
|
|
116
|
-
recoveryCodes: array(string()),
|
|
117
|
-
}),
|
|
112
|
+
result: TotpRecoveryCodesResult,
|
|
118
113
|
credentials: true,
|
|
119
114
|
},
|
|
120
115
|
disableTotp: {
|
|
@@ -142,17 +137,13 @@ export function getAuthenticationApiEndpointsDefinition(additionalTokenPayloadSc
|
|
|
142
137
|
token: string(),
|
|
143
138
|
invalidateOtherSessions: optional(boolean()),
|
|
144
139
|
}),
|
|
145
|
-
result:
|
|
146
|
-
recoveryCodes: array(string()),
|
|
147
|
-
}),
|
|
140
|
+
result: TotpRecoveryCodesResult,
|
|
148
141
|
credentials: true,
|
|
149
142
|
},
|
|
150
143
|
getTotpStatus: {
|
|
151
144
|
resource: 'totp/status',
|
|
152
145
|
method: 'GET',
|
|
153
|
-
result:
|
|
154
|
-
active: boolean(),
|
|
155
|
-
}),
|
|
146
|
+
result: TotpStatusResult,
|
|
156
147
|
credentials: true,
|
|
157
148
|
},
|
|
158
149
|
refresh: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AfterResolve } from '../../injector/index.js';
|
|
2
2
|
import { afterResolve } from '../../injector/index.js';
|
|
3
3
|
import type { Record } from '../../types/index.js';
|
|
4
|
-
import type { AuthenticationSession, PasswordCheckResult, TokenPayload } from '../models/index.js';
|
|
4
|
+
import type { AuthenticationSession, PasswordCheckResult, TokenPayload, TotpEnrollmentInitResult, TotpRecoveryCodesResult, TotpStatusResult } from '../models/index.js';
|
|
5
5
|
import type { LoginTotpResult } from '../server/authentication.service.js';
|
|
6
6
|
import type { SubjectInput } from '../types.js';
|
|
7
7
|
/**
|
|
@@ -59,6 +59,7 @@ export declare class AuthenticationClientService<AdditionalTokenPayload extends
|
|
|
59
59
|
readonly impersonator: import("../../signals/api.js").Signal<string | undefined>;
|
|
60
60
|
/** Whether the user is impersonated */
|
|
61
61
|
readonly impersonated: import("../../signals/api.js").Signal<boolean>;
|
|
62
|
+
readonly totpStatus: import("../../signals/api.js").Signal<TotpStatusResult | undefined>;
|
|
62
63
|
/** Current token */
|
|
63
64
|
readonly token$: import("rxjs").Observable<TokenPayload<AdditionalTokenPayload> | undefined>;
|
|
64
65
|
/** Emits when token is available (not undefined) */
|
|
@@ -196,18 +197,13 @@ export declare class AuthenticationClientService<AdditionalTokenPayload extends
|
|
|
196
197
|
* Initiate TOTP enrollment.
|
|
197
198
|
* @returns The secret and URI for enrollment.
|
|
198
199
|
*/
|
|
199
|
-
initEnrollTotp(): Promise<
|
|
200
|
-
secret: string;
|
|
201
|
-
uri: string;
|
|
202
|
-
}>;
|
|
200
|
+
initEnrollTotp(): Promise<TotpEnrollmentInitResult>;
|
|
203
201
|
/**
|
|
204
202
|
* Complete TOTP enrollment.
|
|
205
203
|
* @param token The TOTP token to verify.
|
|
206
204
|
* @returns The recovery codes.
|
|
207
205
|
*/
|
|
208
|
-
completeEnrollTotp(token: string): Promise<
|
|
209
|
-
recoveryCodes: string[];
|
|
210
|
-
}>;
|
|
206
|
+
completeEnrollTotp(token: string): Promise<TotpRecoveryCodesResult>;
|
|
211
207
|
/**
|
|
212
208
|
* Disable TOTP.
|
|
213
209
|
* @param token The TOTP token.
|
|
@@ -226,16 +222,12 @@ export declare class AuthenticationClientService<AdditionalTokenPayload extends
|
|
|
226
222
|
*/
|
|
227
223
|
regenerateRecoveryCodes(token: string, options?: {
|
|
228
224
|
invalidateOtherSessions?: boolean;
|
|
229
|
-
}): Promise<
|
|
230
|
-
recoveryCodes: string[];
|
|
231
|
-
}>;
|
|
225
|
+
}): Promise<TotpRecoveryCodesResult>;
|
|
232
226
|
/**
|
|
233
227
|
* Get TOTP activation status.
|
|
234
228
|
* @returns Whether TOTP is active.
|
|
235
229
|
*/
|
|
236
|
-
getTotpStatus(): Promise<
|
|
237
|
-
active: boolean;
|
|
238
|
-
}>;
|
|
230
|
+
getTotpStatus(): Promise<TotpStatusResult>;
|
|
239
231
|
/**
|
|
240
232
|
* Check a password for requirements.
|
|
241
233
|
* @param password The password to check
|
|
@@ -22,6 +22,7 @@ import { Lock } from '../../lock/index.js';
|
|
|
22
22
|
import { Logger } from '../../logger/index.js';
|
|
23
23
|
import { MessageBus } from '../../message-bus/index.js';
|
|
24
24
|
import { computed, signal, toObservable } from '../../signals/api.js';
|
|
25
|
+
import { deriveAsync } from '../../signals/index.js';
|
|
25
26
|
import { currentTimestampSeconds } from '../../utils/date-time.js';
|
|
26
27
|
import { clamp } from '../../utils/math.js';
|
|
27
28
|
import { timeout } from '../../utils/timing.js';
|
|
@@ -38,6 +39,7 @@ const tokenUpdateBusName = 'AuthenticationService:tokenUpdate';
|
|
|
38
39
|
const loggedOutBusName = 'AuthenticationService:loggedOut';
|
|
39
40
|
const refreshLockResource = 'AuthenticationService:refresh';
|
|
40
41
|
const minRefreshDelay = millisecondsPerMinute;
|
|
42
|
+
const refreshLoopTightLoopDelay = 5 * millisecondsPerSecond;
|
|
41
43
|
const maxRefreshDelay = 15 * millisecondsPerMinute;
|
|
42
44
|
const lockTimeout = 10_000;
|
|
43
45
|
const logoutTimeout = 150;
|
|
@@ -104,6 +106,19 @@ let AuthenticationClientService = class AuthenticationClientService {
|
|
|
104
106
|
impersonator = computed(() => this.token()?.impersonator);
|
|
105
107
|
/** Whether the user is impersonated */
|
|
106
108
|
impersonated = computed(() => isDefined(this.impersonator()));
|
|
109
|
+
totpStatus = deriveAsync(async () => {
|
|
110
|
+
const token = this.token();
|
|
111
|
+
if (isUndefined(token)) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
return await this.getTotpStatus();
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
this.logger.error(error);
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
107
122
|
/** Current token */
|
|
108
123
|
token$ = toObservable(this.token);
|
|
109
124
|
/** Emits when token is available (not undefined) */
|
|
@@ -269,6 +284,9 @@ let AuthenticationClientService = class AuthenticationClientService {
|
|
|
269
284
|
await this.loggingOut;
|
|
270
285
|
return;
|
|
271
286
|
}
|
|
287
|
+
if (!this.isLoggedIn()) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
272
290
|
this.loggingOut = (async () => {
|
|
273
291
|
try {
|
|
274
292
|
await Promise.race([
|
|
@@ -535,8 +553,8 @@ let AuthenticationClientService = class AuthenticationClientService {
|
|
|
535
553
|
const newBuffer = calculateRefreshBufferSeconds(newToken);
|
|
536
554
|
const stillNeedsRefresh = this.forceRefreshRequested() || (newNow >= newToken.exp - newBuffer);
|
|
537
555
|
if (stillNeedsRefresh) {
|
|
538
|
-
this.logger.warn('Token still needs refresh after attempt. Waiting
|
|
539
|
-
await waitForNextAction(
|
|
556
|
+
this.logger.warn('Token still needs refresh after attempt. Waiting briefly to avoid tight loop.');
|
|
557
|
+
await waitForNextAction(refreshLoopTightLoopDelay, newToken.exp);
|
|
540
558
|
}
|
|
541
559
|
}
|
|
542
560
|
await waitForNextAction(100, newToken?.exp);
|
|
@@ -552,7 +570,7 @@ let AuthenticationClientService = class AuthenticationClientService {
|
|
|
552
570
|
}
|
|
553
571
|
catch (error) {
|
|
554
572
|
this.logger.error(error);
|
|
555
|
-
await waitForNextAction(
|
|
573
|
+
await waitForNextAction(refreshLoopTightLoopDelay, token.exp);
|
|
556
574
|
}
|
|
557
575
|
}
|
|
558
576
|
}
|
|
@@ -560,7 +578,7 @@ let AuthenticationClientService = class AuthenticationClientService {
|
|
|
560
578
|
this.logger.error(error);
|
|
561
579
|
this.errorSubject.next(error);
|
|
562
580
|
const isUnrecoverable = unrecoverableErrors.some((errorType) => isInstanceOf(error, errorType))
|
|
563
|
-
|| (error
|
|
581
|
+
|| (isInstanceOf(error, HttpError) && ((error.response?.statusCode == 400) || (error.response?.statusCode == 401) || (error.response?.statusCode == 404)));
|
|
564
582
|
if (isUnrecoverable) {
|
|
565
583
|
await this.logout();
|
|
566
584
|
}
|
|
@@ -26,4 +26,4 @@ export type AuthenticationClientModuleConfig = {
|
|
|
26
26
|
* @param config Configuration
|
|
27
27
|
* @param injector The injector to use. If not provided, the current injector is used.
|
|
28
28
|
*/
|
|
29
|
-
export declare function configureAuthenticationClient(config
|
|
29
|
+
export declare function configureAuthenticationClient(config?: AuthenticationClientModuleConfig | undefined, injector?: Injector | null): void;
|
|
@@ -9,14 +9,14 @@ import { AUTHENTICATION_API_CLIENT, INITIAL_AUTHENTICATION_DATA } from './tokens
|
|
|
9
9
|
* @param config Configuration
|
|
10
10
|
* @param injector The injector to use. If not provided, the current injector is used.
|
|
11
11
|
*/
|
|
12
|
-
export function configureAuthenticationClient(config, injector = getCurrentInjector()) {
|
|
13
|
-
if (isDefined(config
|
|
12
|
+
export function configureAuthenticationClient(config = undefined, injector = getCurrentInjector()) {
|
|
13
|
+
if (isDefined(config?.authenticationApiClient)) {
|
|
14
14
|
(injector ?? Injector).registerSingleton(AUTHENTICATION_API_CLIENT, { useToken: config.authenticationApiClient });
|
|
15
15
|
}
|
|
16
|
-
if (isDefined(config
|
|
16
|
+
if (isDefined(config?.initialAuthenticationData)) {
|
|
17
17
|
(injector ?? Injector).register(INITIAL_AUTHENTICATION_DATA, { useValue: config.initialAuthenticationData });
|
|
18
18
|
}
|
|
19
|
-
if (config
|
|
19
|
+
if (config?.registerMiddleware == true) {
|
|
20
20
|
(injector ?? Injector).register(HTTP_CLIENT_MIDDLEWARE, {
|
|
21
21
|
useFactory(_, context) {
|
|
22
22
|
const authenticationService = context.resolve(forwardRef(() => AuthenticationClientService, 'object'));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
|
|
2
|
+
export declare class TotpEnrollmentInitResult {
|
|
3
|
+
secret: string;
|
|
4
|
+
uri: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class TotpRecoveryCodesResult {
|
|
7
|
+
recoveryCodes: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class TotpStatusResult {
|
|
10
|
+
active: boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
import { Array, BooleanProperty, StringProperty } from '../../schema/index.js';
|
|
12
|
+
export class TotpEnrollmentInitResult {
|
|
13
|
+
secret;
|
|
14
|
+
uri;
|
|
15
|
+
}
|
|
16
|
+
__decorate([
|
|
17
|
+
StringProperty(),
|
|
18
|
+
__metadata("design:type", String)
|
|
19
|
+
], TotpEnrollmentInitResult.prototype, "secret", void 0);
|
|
20
|
+
__decorate([
|
|
21
|
+
StringProperty(),
|
|
22
|
+
__metadata("design:type", String)
|
|
23
|
+
], TotpEnrollmentInitResult.prototype, "uri", void 0);
|
|
24
|
+
export class TotpRecoveryCodesResult {
|
|
25
|
+
recoveryCodes;
|
|
26
|
+
}
|
|
27
|
+
__decorate([
|
|
28
|
+
Array(String),
|
|
29
|
+
__metadata("design:type", Array)
|
|
30
|
+
], TotpRecoveryCodesResult.prototype, "recoveryCodes", void 0);
|
|
31
|
+
export class TotpStatusResult {
|
|
32
|
+
active;
|
|
33
|
+
}
|
|
34
|
+
__decorate([
|
|
35
|
+
BooleanProperty(),
|
|
36
|
+
__metadata("design:type", Boolean)
|
|
37
|
+
], TotpStatusResult.prototype, "active", void 0);
|
|
@@ -26,9 +26,9 @@ export declare class AuthenticationApiController<AdditionalTokenPayload extends
|
|
|
26
26
|
* @param parameters The parameters for the request.
|
|
27
27
|
* @returns The token result.
|
|
28
28
|
*/
|
|
29
|
-
login({ request, parameters, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'login'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'login'>>;
|
|
30
|
-
loginVerifyTotp({ request, parameters, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginVerifyTotp'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginVerifyTotp'>>;
|
|
31
|
-
loginRecovery({ request, parameters, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginRecovery'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginRecovery'>>;
|
|
29
|
+
login({ request, parameters, tryGetToken, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'login'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'login'>>;
|
|
30
|
+
loginVerifyTotp({ request, parameters, tryGetToken, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginVerifyTotp'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginVerifyTotp'>>;
|
|
31
|
+
loginRecovery({ request, parameters, tryGetToken, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginRecovery'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'loginRecovery'>>;
|
|
32
32
|
initEnrollTotp({ getToken, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'initEnrollTotp'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'initEnrollTotp'>>;
|
|
33
33
|
completeEnrollTotp({ request, getToken, parameters, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'completeEnrollTotp'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'completeEnrollTotp'>>;
|
|
34
34
|
disableTotp({ request, getToken, parameters, getAuditor }: ApiRequestContext<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'disableTotp'>): Promise<ApiServerResult<AuthenticationApiDefinition<AdditionalTokenPayload, AuthenticationData, AdditionalInitPasswordResetData>, 'disableTotp'>>;
|
|
@@ -16,7 +16,7 @@ import { inject } from '../../injector/index.js';
|
|
|
16
16
|
import { Logger } from '../../logger/logger.js';
|
|
17
17
|
import { RateLimiter } from '../../rate-limit/index.js';
|
|
18
18
|
import { currentTimestampSeconds } from '../../utils/date-time.js';
|
|
19
|
-
import { isDefined } from '../../utils/type-guards.js';
|
|
19
|
+
import { isDefined, isNotNull } from '../../utils/type-guards.js';
|
|
20
20
|
import { millisecondsPerMinute } from '../../utils/units.js';
|
|
21
21
|
import { authenticationApiDefinition, getAuthenticationApiDefinition } from '../authentication.api.js';
|
|
22
22
|
import { AuthenticationService, AuthenticationServiceOptions } from './authentication.service.js';
|
|
@@ -49,24 +49,51 @@ let AuthenticationApiController = AuthenticationApiController_1 = class Authenti
|
|
|
49
49
|
* @param parameters The parameters for the request.
|
|
50
50
|
* @returns The token result.
|
|
51
51
|
*/
|
|
52
|
-
async login({ request, parameters, getAuditor }) {
|
|
52
|
+
async login({ request, parameters, tryGetToken, getAuditor }) {
|
|
53
53
|
const auditor = await getAuditor();
|
|
54
|
+
try {
|
|
55
|
+
const token = await tryGetToken();
|
|
56
|
+
if (isNotNull(token)) {
|
|
57
|
+
await this.authenticationService.endSession(token.payload.session, auditor);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.#logger.error('Error validating existing token during login:', error);
|
|
62
|
+
}
|
|
54
63
|
const subjectResource = `${parameters.tenantId ?? NIL_UUID}:${parameters.subject}`;
|
|
55
64
|
const actualSubject = await this.authenticationService.tryResolveSubject({ tenantId: parameters.tenantId, subject: parameters.subject });
|
|
56
65
|
await this.enforceRateLimit(request.ip, subjectResource, auditor, actualSubject?.id ?? NIL_UUID, 'login');
|
|
57
66
|
const result = await this.authenticationService.login({ tenantId: parameters.tenantId, subject: parameters.subject }, parameters.password, parameters.data, auditor, parameters.remember);
|
|
58
67
|
return this.getLoginResponse(result);
|
|
59
68
|
}
|
|
60
|
-
async loginVerifyTotp({ request, parameters, getAuditor }) {
|
|
69
|
+
async loginVerifyTotp({ request, parameters, tryGetToken, getAuditor }) {
|
|
61
70
|
const auditor = await getAuditor();
|
|
71
|
+
try {
|
|
72
|
+
const token = await tryGetToken();
|
|
73
|
+
if (isNotNull(token)) {
|
|
74
|
+
await this.authenticationService.endSession(token.payload.session, auditor);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
this.#logger.error('Error validating existing token during login:', error);
|
|
79
|
+
}
|
|
62
80
|
const validatedChallengeToken = await this.authenticationService.validateTotpChallengeToken(parameters.challengeToken);
|
|
63
81
|
const subjectResource = `${validatedChallengeToken.payload.tenant}:${validatedChallengeToken.payload.subject}`;
|
|
64
82
|
await this.enforceRateLimit(request.ip, subjectResource, auditor, validatedChallengeToken.payload.subject, 'login-verify-totp');
|
|
65
83
|
const result = await this.authenticationService.loginVerifyTotp(parameters.challengeToken, parameters.token, auditor);
|
|
66
84
|
return this.getLoginResponse(result);
|
|
67
85
|
}
|
|
68
|
-
async loginRecovery({ request, parameters, getAuditor }) {
|
|
86
|
+
async loginRecovery({ request, parameters, tryGetToken, getAuditor }) {
|
|
69
87
|
const auditor = await getAuditor();
|
|
88
|
+
try {
|
|
89
|
+
const token = await tryGetToken();
|
|
90
|
+
if (isNotNull(token)) {
|
|
91
|
+
await this.authenticationService.endSession(token.payload.session, auditor);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.#logger.error('Error validating existing token during login:', error);
|
|
96
|
+
}
|
|
70
97
|
const validatedChallengeToken = await this.authenticationService.validateTotpChallengeToken(parameters.challengeToken);
|
|
71
98
|
const subjectResource = `${validatedChallengeToken.payload.tenant}:${validatedChallengeToken.payload.subject}`;
|
|
72
99
|
await this.enforceRateLimit(request.ip, subjectResource, auditor, validatedChallengeToken.payload.subject, 'login-recovery');
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Auditor } from '../../audit/index.js';
|
|
3
3
|
import { type Argon2Params, type TotpHashAlgorithm } from '../../cryptography/index.js';
|
|
4
4
|
import type { Record, TypedOmit } from '../../types/index.js';
|
|
5
|
-
import { AuthenticationSession, AuthenticationTotp, Subject, type PasswordCheckResult, type PasswordResetToken, type RefreshToken, type Token, type TotpChallengeToken } from '../models/index.js';
|
|
5
|
+
import { AuthenticationSession, AuthenticationTotp, Subject, TotpEnrollmentInitResult, TotpRecoveryCodesResult, TotpStatusResult, type PasswordCheckResult, type PasswordResetToken, type RefreshToken, type Token, type TotpChallengeToken } from '../models/index.js';
|
|
6
6
|
import type { SubjectInput } from '../types.js';
|
|
7
7
|
import { type PasswordTestResult } from './authentication-password-requirements.validator.js';
|
|
8
8
|
/**
|
|
@@ -456,23 +456,14 @@ export declare class AuthenticationService<AdditionalTokenPayload extends Record
|
|
|
456
456
|
private createPasswordResetToken;
|
|
457
457
|
private getHash;
|
|
458
458
|
tryGetTotp(tenantId: string, subjectId: string): Promise<AuthenticationTotp | undefined>;
|
|
459
|
-
getTotpStatus(tenantId: string, subjectId: string): Promise<
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
initEnrollTotp(tenantId: string, subjectId: string, auditor: Auditor): Promise<{
|
|
463
|
-
secret: string;
|
|
464
|
-
uri: string;
|
|
465
|
-
}>;
|
|
466
|
-
completeEnrollTotp(tenantId: string, subjectId: string, token: string, auditor: Auditor): Promise<{
|
|
467
|
-
recoveryCodes: string[];
|
|
468
|
-
}>;
|
|
459
|
+
getTotpStatus(tenantId: string, subjectId: string): Promise<TotpStatusResult>;
|
|
460
|
+
initEnrollTotp(tenantId: string, subjectId: string, auditor: Auditor): Promise<TotpEnrollmentInitResult>;
|
|
461
|
+
completeEnrollTotp(tenantId: string, subjectId: string, token: string, auditor: Auditor): Promise<TotpRecoveryCodesResult>;
|
|
469
462
|
disableTotp(tenantId: string, subjectId: string, token: string, auditor: Auditor): Promise<void>;
|
|
470
463
|
disableTotpWithRecoveryCode(tenantId: string, subjectId: string, recoveryCode: string, auditor: Auditor): Promise<void>;
|
|
471
464
|
regenerateRecoveryCodes(tenantId: string, subjectId: string, token: string, auditor: Auditor, options?: {
|
|
472
465
|
invalidateOtherSessions?: boolean;
|
|
473
|
-
}): Promise<
|
|
474
|
-
recoveryCodes: string[];
|
|
475
|
-
}>;
|
|
466
|
+
}): Promise<TotpRecoveryCodesResult>;
|
|
476
467
|
loginVerifyTotp(challengeTokenString: string, token: string, auditor: Auditor): Promise<LoginSuccessResult<AdditionalTokenPayload>>;
|
|
477
468
|
loginRecovery(challengeTokenString: string, recoveryCode: string, auditor: Auditor): Promise<LoginSuccessResult<AdditionalTokenPayload>>;
|
|
478
469
|
validateTotpChallengeToken(tokenString: string): Promise<TotpChallengeToken<AuthenticationData>>;
|
|
@@ -23,7 +23,7 @@ import { isUuid } from '../../utils/patterns.js';
|
|
|
23
23
|
import { getRandomBytes, getRandomString } from '../../utils/random.js';
|
|
24
24
|
import { isDefined, isString, isUndefined } from '../../utils/type-guards.js';
|
|
25
25
|
import { millisecondsPerDay, millisecondsPerHour, millisecondsPerMinute } from '../../utils/units.js';
|
|
26
|
-
import { AuthenticationPassword, AuthenticationSession, AuthenticationTotp, AuthenticationTotpRecoveryCode, AuthenticationUsedTotpToken, Subject, SubjectStatus, TotpStatus, User } from '../models/index.js';
|
|
26
|
+
import { AuthenticationPassword, AuthenticationSession, AuthenticationTotp, AuthenticationTotpRecoveryCode, AuthenticationUsedTotpToken, Subject, SubjectStatus, TotpEnrollmentInitResult, TotpRecoveryCodesResult, TotpStatus, TotpStatusResult, User } from '../models/index.js';
|
|
27
27
|
import { AuthenticationAncillaryService, GetTokenPayloadContextAction } from './authentication-ancillary.service.js';
|
|
28
28
|
import { AuthenticationPasswordRequirementsValidator } from './authentication-password-requirements.validator.js';
|
|
29
29
|
import { getPasswordResetTokenFromString, getRefreshTokenFromString, getTokenFromString } from './helper.js';
|
|
@@ -88,11 +88,11 @@ const JWT_ID_LENGTH = 24;
|
|
|
88
88
|
const REFRESH_TOKEN_SECRET_LENGTH = 64;
|
|
89
89
|
const SALT_LENGTH = 32;
|
|
90
90
|
export const DEFAULT_TOTP_OPTIONS = {
|
|
91
|
-
codeHashAlgorithm: 'SHA-
|
|
91
|
+
codeHashAlgorithm: 'SHA-1',
|
|
92
92
|
recoveryCodeHashOptions: {
|
|
93
93
|
algorithm: {
|
|
94
94
|
name: 'Argon2id',
|
|
95
|
-
memory:
|
|
95
|
+
memory: 256 * 1024, // 256 MiB
|
|
96
96
|
parallelism: 4,
|
|
97
97
|
passes: 3,
|
|
98
98
|
},
|
|
@@ -861,7 +861,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
861
861
|
}
|
|
862
862
|
async getTotpStatus(tenantId, subjectId) {
|
|
863
863
|
const totp = await this.tryGetTotp(tenantId, subjectId);
|
|
864
|
-
return {
|
|
864
|
+
return {
|
|
865
|
+
active: totp?.status == TotpStatus.Active,
|
|
866
|
+
};
|
|
865
867
|
}
|
|
866
868
|
async initEnrollTotp(tenantId, subjectId, auditor) {
|
|
867
869
|
const authAuditor = auditor.fork(AuthenticationService_1.name);
|
package/core.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import { Injector } from './injector/index.js';
|
|
2
1
|
declare global {
|
|
3
2
|
var tstdlLoaded: boolean | undefined;
|
|
4
3
|
}
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated Usage of `getGlobalInjector` should be avoided. Use `Application` scoped injector instead.
|
|
7
|
-
*/
|
|
8
|
-
export declare function getGlobalInjector(): Injector;
|
|
9
4
|
export declare function isDevMode(): boolean;
|
|
10
5
|
export declare function isProdMode(): boolean;
|
|
11
6
|
export declare function enableProdMode(): void;
|
package/core.js
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import { Injector } from './injector/index.js';
|
|
2
1
|
if (globalThis.tstdlLoaded == true) {
|
|
3
2
|
console.error(new Error('tstdl seems to be loaded multiple times. This is likely an error as some modules won\'t work as intended this way.'));
|
|
4
3
|
}
|
|
5
4
|
globalThis.tstdlLoaded = true;
|
|
6
|
-
let globalInjector;
|
|
7
5
|
let _isDevMode = true;
|
|
8
|
-
/**
|
|
9
|
-
* @deprecated Usage of `getGlobalInjector` should be avoided. Use `Application` scoped injector instead.
|
|
10
|
-
*/
|
|
11
|
-
export function getGlobalInjector() {
|
|
12
|
-
return globalInjector ??= new Injector('GlobalInjector');
|
|
13
|
-
}
|
|
14
6
|
export function isDevMode() {
|
|
15
7
|
return _isDevMode;
|
|
16
8
|
}
|