@getstrata/bootstrap 0.2.65 → 0.2.68
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/CHANGELOG.md +17 -0
- package/README.md +5 -5
- package/dist/bootstrap/createWebRoutes.d.ts +7 -3
- package/dist/bootstrap/dogfoodApp.d.ts +7 -0
- package/dist/bootstrap/public-api.d.ts +1 -0
- package/dist/bootstrap/rateLimit.d.ts +10 -0
- package/dist/bootstrap/web/session.d.ts +18 -3
- package/dist/entries/buildModuleRoutes.js +35 -30
- package/dist/entries/buildWebModuleRoutes.js +35 -30
- package/dist/entries/cache/modelCacheTags.js +7 -2
- package/dist/entries/context.js +13 -163
- package/dist/entries/createRoutes.js +60 -880
- package/dist/entries/createWebRoutes.js +39 -36
- package/dist/entries/dependencies.js +13 -163
- package/dist/entries/discoverModules.js +7 -2
- package/dist/entries/httpKernel.js +28 -28
- package/dist/entries/listeners/invalidateCacheOnModelWrite.js +7 -2
- package/dist/entries/providers/view.js +5 -160
- package/dist/entries/providers.js +13 -163
- package/dist/entries/secretsGuard.js +25 -40
- package/dist/entries/web/routing.js +28 -28
- package/dist/entries/web/session.js +24 -10
- package/dist/index.js +93 -246
- package/package.json +2 -2
- package/dist/bootstrap/scimRoutes.d.ts +0 -24
package/dist/index.js
CHANGED
|
@@ -52,7 +52,32 @@ import { isPublicReadsEnabled } from "@getstrata/core/security/publicReads";
|
|
|
52
52
|
import { createTenantMiddleware } from "@getstrata/core/tenant/tenantMiddleware";
|
|
53
53
|
import { createTracingMiddleware } from "@getstrata/core/tracing/tracingMiddleware";
|
|
54
54
|
|
|
55
|
-
// ../../src/config
|
|
55
|
+
// ../../src/bootstrap/config.ts
|
|
56
|
+
import {
|
|
57
|
+
CORE_ABILITY_CHECKER_TOKEN,
|
|
58
|
+
CORE_AUTH_TOKEN,
|
|
59
|
+
CORE_AUTH_USER_DIRECTORY_TOKEN,
|
|
60
|
+
CORE_CACHE_TOKEN,
|
|
61
|
+
CORE_CONFIG_TOKEN,
|
|
62
|
+
CORE_EVENT_BUS_TOKEN,
|
|
63
|
+
CORE_POLICY_GATE_TOKEN,
|
|
64
|
+
CORE_QUEUE_TOKEN,
|
|
65
|
+
CORE_TOKEN_SERVICE_TOKEN
|
|
66
|
+
} from "@getstrata/core/contracts/serviceTokens";
|
|
67
|
+
var APP_PORT_CONFIG_KEY = "app.port";
|
|
68
|
+
var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
|
|
69
|
+
var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
70
|
+
var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
71
|
+
var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
72
|
+
var DATABASE_URL_CONFIG_KEY = "database.url";
|
|
73
|
+
var DEFAULT_APP_PORT = 3000;
|
|
74
|
+
var DEFAULT_CACHE_TTL_MS = 3600000;
|
|
75
|
+
var DEFAULT_CACHE_MAX_ENTRIES = 100;
|
|
76
|
+
var DEFAULT_CACHE_DRIVER = "array";
|
|
77
|
+
var DEFAULT_API_TOKEN = "";
|
|
78
|
+
var DEFAULT_QUEUE_DRIVER = "sync";
|
|
79
|
+
|
|
80
|
+
// ../../src/bootstrap/rateLimit.ts
|
|
56
81
|
var LOCAL_LOGIN_RATE_LIMIT = {
|
|
57
82
|
maxAttempts: 100,
|
|
58
83
|
decaySeconds: 60
|
|
@@ -98,31 +123,6 @@ function resolveRegisterRateLimit() {
|
|
|
98
123
|
};
|
|
99
124
|
}
|
|
100
125
|
|
|
101
|
-
// ../../src/bootstrap/config.ts
|
|
102
|
-
import {
|
|
103
|
-
CORE_ABILITY_CHECKER_TOKEN,
|
|
104
|
-
CORE_AUTH_TOKEN,
|
|
105
|
-
CORE_AUTH_USER_DIRECTORY_TOKEN,
|
|
106
|
-
CORE_CACHE_TOKEN,
|
|
107
|
-
CORE_CONFIG_TOKEN,
|
|
108
|
-
CORE_EVENT_BUS_TOKEN,
|
|
109
|
-
CORE_POLICY_GATE_TOKEN,
|
|
110
|
-
CORE_QUEUE_TOKEN,
|
|
111
|
-
CORE_TOKEN_SERVICE_TOKEN
|
|
112
|
-
} from "@getstrata/core/contracts/serviceTokens";
|
|
113
|
-
var APP_PORT_CONFIG_KEY = "app.port";
|
|
114
|
-
var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
|
|
115
|
-
var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
116
|
-
var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
117
|
-
var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
118
|
-
var DATABASE_URL_CONFIG_KEY = "database.url";
|
|
119
|
-
var DEFAULT_APP_PORT = 3000;
|
|
120
|
-
var DEFAULT_CACHE_TTL_MS = 3600000;
|
|
121
|
-
var DEFAULT_CACHE_MAX_ENTRIES = 100;
|
|
122
|
-
var DEFAULT_CACHE_DRIVER = "array";
|
|
123
|
-
var DEFAULT_API_TOKEN = "";
|
|
124
|
-
var DEFAULT_QUEUE_DRIVER = "sync";
|
|
125
|
-
|
|
126
126
|
// ../../src/bootstrap/httpKernel.ts
|
|
127
127
|
class HttpKernel {
|
|
128
128
|
dependencies;
|
|
@@ -193,7 +193,7 @@ class HttpKernel {
|
|
|
193
193
|
wrapWeb(handler) {
|
|
194
194
|
return withErrorHandling(this.wrap("web", handler));
|
|
195
195
|
}
|
|
196
|
-
wrapWebGuest(handler, home = "/
|
|
196
|
+
wrapWebGuest(handler, home = "/") {
|
|
197
197
|
const auth = this.dependencies.container.resolve(CORE_AUTH_TOKEN);
|
|
198
198
|
return this.wrapWeb(async (request) => {
|
|
199
199
|
const user = await auth.resolve(request);
|
|
@@ -353,7 +353,12 @@ function readDiscoverModulesState() {
|
|
|
353
353
|
return state;
|
|
354
354
|
}
|
|
355
355
|
function configureModulesDirectory(modulesDir) {
|
|
356
|
-
readDiscoverModulesState()
|
|
356
|
+
const state = readDiscoverModulesState();
|
|
357
|
+
if (state.configuredModulesDir !== modulesDir) {
|
|
358
|
+
state.appModules.length = 0;
|
|
359
|
+
state.modulesReady = undefined;
|
|
360
|
+
}
|
|
361
|
+
state.configuredModulesDir = modulesDir;
|
|
357
362
|
}
|
|
358
363
|
function resolveModulesDirectory(options) {
|
|
359
364
|
const state = readDiscoverModulesState();
|
|
@@ -363,7 +368,7 @@ function resolveModulesDirectory(options) {
|
|
|
363
368
|
if (state.configuredModulesDir) {
|
|
364
369
|
return state.configuredModulesDir;
|
|
365
370
|
}
|
|
366
|
-
throw new Error("configureModulesDirectory() must be called before discovering modules.
|
|
371
|
+
throw new Error("configureModulesDirectory() must be called before discovering modules. The app preload (or starter) should call it.");
|
|
367
372
|
}
|
|
368
373
|
async function loadDiscoveredModules(options) {
|
|
369
374
|
const modulesDirectory = resolveModulesDirectory(options);
|
|
@@ -575,7 +580,7 @@ import { validateEnv } from "@getstrata/core/config/envSchema";
|
|
|
575
580
|
|
|
576
581
|
// ../../src/config/app.ts
|
|
577
582
|
var appConfig = {
|
|
578
|
-
name: process.env.APP_NAME?.trim() || "
|
|
583
|
+
name: process.env.APP_NAME?.trim() || "Strata",
|
|
579
584
|
env: process.env.APP_ENV ?? "local",
|
|
580
585
|
debug: (process.env.APP_DEBUG ?? "true") !== "false",
|
|
581
586
|
url: process.env.APP_URL ?? "http://localhost:3000",
|
|
@@ -871,7 +876,6 @@ var storageProvider = {
|
|
|
871
876
|
var storage_default = storageProvider;
|
|
872
877
|
|
|
873
878
|
// ../../src/bootstrap/providers/view.ts
|
|
874
|
-
import { resolveMembershipLookup } from "@getstrata/core/auth/membershipContext";
|
|
875
879
|
import { currentRequestMeta } from "@getstrata/core/http/requestMetaContext";
|
|
876
880
|
import { appDisplayName } from "@getstrata/core/runtime/appKeyPrefix";
|
|
877
881
|
import { isViewsEnabled as isViewsEnabled2 } from "@getstrata/core/runtime/frontendMode";
|
|
@@ -883,148 +887,6 @@ import {
|
|
|
883
887
|
errorTemplateName,
|
|
884
888
|
resolveWebLayoutData
|
|
885
889
|
} from "@getstrata/core/view";
|
|
886
|
-
|
|
887
|
-
// ../../src/modules/organization/repository.ts
|
|
888
|
-
import { BaseRepository } from "@getstrata/core/database/baseRepository";
|
|
889
|
-
import { NotFoundError } from "@getstrata/core/errors/http";
|
|
890
|
-
import { currentTenantId } from "@getstrata/core/tenant/tenantContext";
|
|
891
|
-
|
|
892
|
-
// ../../src/modules/organization/table.ts
|
|
893
|
-
import { defineTable } from "@getstrata/core/database/table";
|
|
894
|
-
|
|
895
|
-
// ../../src/domain/workhub.ts
|
|
896
|
-
var ORGANIZATION_TABLE = "organization";
|
|
897
|
-
|
|
898
|
-
// ../../src/modules/organization/table.ts
|
|
899
|
-
var organizationTable = defineTable({
|
|
900
|
-
name: ORGANIZATION_TABLE,
|
|
901
|
-
primaryKey: "id",
|
|
902
|
-
columns: ["id", "tenant_id", "name", "slug", "created_at", "updated_at", "deleted_at"],
|
|
903
|
-
softDeletes: true,
|
|
904
|
-
defaultOrderBy: { column: "id", direction: "ASC" }
|
|
905
|
-
});
|
|
906
|
-
|
|
907
|
-
// ../../src/modules/organization/repository.ts
|
|
908
|
-
class OrganizationRepository extends BaseRepository {
|
|
909
|
-
constructor() {
|
|
910
|
-
super(organizationTable);
|
|
911
|
-
}
|
|
912
|
-
async findBySlug(slug) {
|
|
913
|
-
return await this.firstOrNull({ slug });
|
|
914
|
-
}
|
|
915
|
-
async listForTenant(options) {
|
|
916
|
-
return await this.findAll({
|
|
917
|
-
limit: options.limit,
|
|
918
|
-
offset: options.offset,
|
|
919
|
-
where: { tenant_id: options.tenantId ?? currentTenantId() }
|
|
920
|
-
});
|
|
921
|
-
}
|
|
922
|
-
async countForTenant(tenantId = currentTenantId()) {
|
|
923
|
-
return await this.countWhere({ tenant_id: tenantId });
|
|
924
|
-
}
|
|
925
|
-
async findForTenantOrThrow(id, tenantId = currentTenantId()) {
|
|
926
|
-
const organization = await this.findById(id);
|
|
927
|
-
if (!organization || organization.tenant_id !== tenantId) {
|
|
928
|
-
throw new NotFoundError(`SCIM group ${id} not found.`);
|
|
929
|
-
}
|
|
930
|
-
return organization;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
var repository_default = OrganizationRepository;
|
|
934
|
-
|
|
935
|
-
// ../../src/modules/user/repository.ts
|
|
936
|
-
import {
|
|
937
|
-
emailLookupForQuery,
|
|
938
|
-
protectEmail,
|
|
939
|
-
revealEmail
|
|
940
|
-
} from "@getstrata/core/crypto/fieldEncryption";
|
|
941
|
-
import { revealMfaSecret } from "@getstrata/core/crypto/mfaSecret";
|
|
942
|
-
import { BaseRepository as BaseRepository2 } from "@getstrata/core/database/baseRepository";
|
|
943
|
-
import { currentTenantId as currentTenantId2 } from "@getstrata/core/tenant/tenantContext";
|
|
944
|
-
|
|
945
|
-
// ../../src/modules/user/table.ts
|
|
946
|
-
import { defineTable as defineTable2 } from "@getstrata/core/database/table";
|
|
947
|
-
var userTable = defineTable2({
|
|
948
|
-
name: "users",
|
|
949
|
-
primaryKey: "id",
|
|
950
|
-
columns: [
|
|
951
|
-
"id",
|
|
952
|
-
"name",
|
|
953
|
-
"email",
|
|
954
|
-
"email_lookup",
|
|
955
|
-
"role",
|
|
956
|
-
"tenant_id",
|
|
957
|
-
"password_hash",
|
|
958
|
-
"email_verified_at",
|
|
959
|
-
"mfa_secret",
|
|
960
|
-
"mfa_enabled",
|
|
961
|
-
"mfa_recovery_codes",
|
|
962
|
-
"profile_photo_path",
|
|
963
|
-
"session_valid_after",
|
|
964
|
-
"current_organization_id",
|
|
965
|
-
"created_at",
|
|
966
|
-
"updated_at"
|
|
967
|
-
],
|
|
968
|
-
defaultOrderBy: { column: "id", direction: "ASC" }
|
|
969
|
-
});
|
|
970
|
-
|
|
971
|
-
// ../../src/modules/user/repository.ts
|
|
972
|
-
class UserRepository extends BaseRepository2 {
|
|
973
|
-
constructor() {
|
|
974
|
-
super(userTable);
|
|
975
|
-
}
|
|
976
|
-
decode(record) {
|
|
977
|
-
return {
|
|
978
|
-
...record,
|
|
979
|
-
email: revealEmail(record.email),
|
|
980
|
-
mfa_secret: revealMfaSecret(record.mfa_secret)
|
|
981
|
-
};
|
|
982
|
-
}
|
|
983
|
-
async findById(id) {
|
|
984
|
-
const record = await super.findById(id);
|
|
985
|
-
return record ? this.decode(record) : null;
|
|
986
|
-
}
|
|
987
|
-
async findAll(options = {}) {
|
|
988
|
-
const records = await super.findAll(options);
|
|
989
|
-
return records.map((record) => this.decode(record));
|
|
990
|
-
}
|
|
991
|
-
async create(values) {
|
|
992
|
-
const email = values.email;
|
|
993
|
-
if (!email) {
|
|
994
|
-
throw new Error("Email is required.");
|
|
995
|
-
}
|
|
996
|
-
const protectedEmail = protectEmail(email);
|
|
997
|
-
const record = await super.create({
|
|
998
|
-
...values,
|
|
999
|
-
tenant_id: values.tenant_id ?? currentTenantId2(),
|
|
1000
|
-
email: protectedEmail.storedEmail,
|
|
1001
|
-
email_lookup: protectedEmail.emailLookup,
|
|
1002
|
-
password_hash: values.password_hash ?? ""
|
|
1003
|
-
});
|
|
1004
|
-
return this.decode(record);
|
|
1005
|
-
}
|
|
1006
|
-
async updateByIdOrThrow(id, values, errorFactory) {
|
|
1007
|
-
const changes = { ...values };
|
|
1008
|
-
if (values.email !== undefined) {
|
|
1009
|
-
const protectedEmail = protectEmail(values.email);
|
|
1010
|
-
changes.email = protectedEmail.storedEmail;
|
|
1011
|
-
changes.email_lookup = protectedEmail.emailLookup;
|
|
1012
|
-
}
|
|
1013
|
-
const record = await super.updateByIdOrThrow(id, changes, errorFactory);
|
|
1014
|
-
return this.decode(record);
|
|
1015
|
-
}
|
|
1016
|
-
async findByEmail(email) {
|
|
1017
|
-
const records = await this.findWhere({ email_lookup: emailLookupForQuery(email) }, { limit: 1 });
|
|
1018
|
-
const record = records[0];
|
|
1019
|
-
return record ? this.decode(record) : null;
|
|
1020
|
-
}
|
|
1021
|
-
async countForTenant(tenantId = currentTenantId2()) {
|
|
1022
|
-
return await this.countWhere({ tenant_id: tenantId });
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
var repository_default2 = UserRepository;
|
|
1026
|
-
|
|
1027
|
-
// ../../src/bootstrap/providers/view.ts
|
|
1028
890
|
var CORE_VIEW_TOKEN = "core.view";
|
|
1029
891
|
var VIEW_DIRECTORY_CONFIG_KEY = "view.directory";
|
|
1030
892
|
var viewProvider = {
|
|
@@ -1038,23 +900,11 @@ var viewProvider = {
|
|
|
1038
900
|
const engine = new EtaViewEngine(viewsDirectory, (request) => resolveWebLayoutData(container, request ?? currentRequestMeta().request));
|
|
1039
901
|
container.set(CORE_VIEW_TOKEN, engine);
|
|
1040
902
|
configureWebLayoutData({
|
|
1041
|
-
extra: async (
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
try {
|
|
1047
|
-
const record = await new repository_default2().findByIdOrThrow(user.id);
|
|
1048
|
-
const memberships = await resolveMembershipLookup().listForUser(record.id);
|
|
1049
|
-
const organizationsRepo = new repository_default;
|
|
1050
|
-
const organizations = (await Promise.all(memberships.map((membership) => organizationsRepo.findById(membership.organization_id)))).filter((organization) => Boolean(organization && !organization.deleted_at));
|
|
1051
|
-
const currentId = record.current_organization_id ?? null;
|
|
1052
|
-
const currentOrganization = organizations.find((organization) => organization.id === currentId) ?? organizations[0] ?? null;
|
|
1053
|
-
return { appName, currentOrganization, organizations };
|
|
1054
|
-
} catch {
|
|
1055
|
-
return { appName, currentOrganization: null, organizations: [] };
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
903
|
+
extra: async () => ({
|
|
904
|
+
appName: appDisplayName(),
|
|
905
|
+
currentOrganization: null,
|
|
906
|
+
organizations: []
|
|
907
|
+
})
|
|
1058
908
|
});
|
|
1059
909
|
configureWebErrorView({
|
|
1060
910
|
render: async (input) => engine.render(errorTemplateName(input.status), {
|
|
@@ -1118,12 +968,10 @@ import { notFoundHtmlResponse } from "@getstrata/core/view";
|
|
|
1118
968
|
function registerRoute(method, path, middleware) {
|
|
1119
969
|
routeRegistry.register({ method, path, middleware });
|
|
1120
970
|
}
|
|
1121
|
-
function createWebRoutes(dependencies) {
|
|
971
|
+
function createWebRoutes(dependencies, options = {}) {
|
|
1122
972
|
const wrappedRoutes = buildWebModuleRoutes(dependencies, {
|
|
1123
973
|
clearRegistry: false,
|
|
1124
|
-
|
|
1125
|
-
"/": () => Response.redirect("/organizations", 302)
|
|
1126
|
-
}
|
|
974
|
+
modules: options.modules
|
|
1127
975
|
});
|
|
1128
976
|
registerRoute("GET", "/", ["global", "web"]);
|
|
1129
977
|
wrappedRoutes["/assets/*"] = async (request) => {
|
|
@@ -1139,12 +987,12 @@ function createWebRoutes(dependencies) {
|
|
|
1139
987
|
registerRoute("GET", "/assets/*", ["global", "web"]);
|
|
1140
988
|
return wrappedRoutes;
|
|
1141
989
|
}
|
|
1142
|
-
function mergeWebRoutes(dependencies, routes) {
|
|
990
|
+
function mergeWebRoutes(dependencies, routes, options = {}) {
|
|
1143
991
|
if (!isViewsEnabled3()) {
|
|
1144
992
|
return routes;
|
|
1145
993
|
}
|
|
1146
994
|
return {
|
|
1147
|
-
...createWebRoutes(dependencies),
|
|
995
|
+
...createWebRoutes(dependencies, options),
|
|
1148
996
|
...routes
|
|
1149
997
|
};
|
|
1150
998
|
}
|
|
@@ -1255,12 +1103,15 @@ import {
|
|
|
1255
1103
|
// ../../src/bootstrap/membershipService.ts
|
|
1256
1104
|
import { resolveMembershipService } from "@getstrata/core/auth/membershipService";
|
|
1257
1105
|
// ../../src/bootstrap/secretsGuard.ts
|
|
1258
|
-
var
|
|
1259
|
-
var
|
|
1260
|
-
var
|
|
1106
|
+
var PUBLISHED_TEST_ADMIN_API_TOKEN = "workhub-admin-test-token";
|
|
1107
|
+
var PUBLISHED_TEST_MEMBER_API_TOKEN = "workhub-member-test-token";
|
|
1108
|
+
var PUBLISHED_TEST_SCIM_BEARER_TOKEN = "workhub-scim-test-token";
|
|
1261
1109
|
var MIN_SESSION_SECRET_LENGTH = 32;
|
|
1262
|
-
var
|
|
1263
|
-
|
|
1110
|
+
var PUBLISHED_TEST_TOKENS = new Set([
|
|
1111
|
+
PUBLISHED_TEST_ADMIN_API_TOKEN,
|
|
1112
|
+
PUBLISHED_TEST_MEMBER_API_TOKEN
|
|
1113
|
+
]);
|
|
1114
|
+
var PUBLISHED_TEST_SCIM_TOKENS = new Set([PUBLISHED_TEST_SCIM_BEARER_TOKEN]);
|
|
1264
1115
|
function isEnabled(value, defaultEnabled) {
|
|
1265
1116
|
if (value === undefined) {
|
|
1266
1117
|
return defaultEnabled;
|
|
@@ -1287,36 +1138,19 @@ function assertSessionSecret(env) {
|
|
|
1287
1138
|
throw new Error("Production startup blocked: set SESSION_SECRET when FRONTEND_MODE=server-htmx (32+ characters).");
|
|
1288
1139
|
}
|
|
1289
1140
|
}
|
|
1290
|
-
function
|
|
1291
|
-
const adminToken = env.ADMIN_API_TOKEN ??
|
|
1292
|
-
const memberToken = env.MEMBER_API_TOKEN ??
|
|
1293
|
-
const scimToken = env.SCIM_BEARER_TOKEN ??
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
throw new Error("Production startup blocked: rotate ADMIN_API_TOKEN and MEMBER_API_TOKEN away from default WorkHub test values.");
|
|
1297
|
-
}
|
|
1298
|
-
if (DEFAULT_SCIM_TOKENS.has(scimToken)) {
|
|
1299
|
-
throw new Error("Production startup blocked: rotate SCIM_BEARER_TOKEN away from default WorkHub test values.");
|
|
1300
|
-
}
|
|
1301
|
-
if (encryptionEnabled && !env.KMS_ENCRYPTION_KEY?.trim()) {
|
|
1302
|
-
throw new Error("Production startup blocked: set KMS_ENCRYPTION_KEY when field encryption is enabled.");
|
|
1303
|
-
}
|
|
1304
|
-
if (!env.SIEM_EXPORT_URL?.trim() && isEnabled(env.FEATURE_SIEM_EXPORT, true)) {
|
|
1305
|
-
console.warn("[secrets] SIEM_EXPORT_URL is not configured; audit logs remain database-only.");
|
|
1306
|
-
}
|
|
1307
|
-
if (isEnabled(env.FEATURE_BILLING, true) && !env.STRIPE_WEBHOOK_SECRET?.trim()) {
|
|
1308
|
-
throw new Error("Production startup blocked: set STRIPE_WEBHOOK_SECRET when billing webhooks are enabled.");
|
|
1309
|
-
}
|
|
1310
|
-
const corsOrigins = (env.CORS_ALLOWED_ORIGINS ?? "*").split(",").map((origin) => origin.trim());
|
|
1311
|
-
if (corsOrigins.includes("*")) {
|
|
1312
|
-
throw new Error("Production startup blocked: set explicit CORS_ALLOWED_ORIGINS instead of wildcard.");
|
|
1141
|
+
function assertPublishedTestTokensRotated(env) {
|
|
1142
|
+
const adminToken = env.ADMIN_API_TOKEN ?? "";
|
|
1143
|
+
const memberToken = env.MEMBER_API_TOKEN ?? "";
|
|
1144
|
+
const scimToken = env.SCIM_BEARER_TOKEN ?? "";
|
|
1145
|
+
if (PUBLISHED_TEST_TOKENS.has(adminToken) || PUBLISHED_TEST_TOKENS.has(memberToken)) {
|
|
1146
|
+
throw new Error("Production startup blocked: rotate ADMIN_API_TOKEN and MEMBER_API_TOKEN away from published test defaults.");
|
|
1313
1147
|
}
|
|
1314
|
-
if (
|
|
1315
|
-
throw new Error("Production startup blocked:
|
|
1316
|
-
}
|
|
1317
|
-
if (!env.OAUTH_STATE_SECRET?.trim()) {
|
|
1318
|
-
throw new Error("Production startup blocked: set OAUTH_STATE_SECRET for OAuth CSRF protection.");
|
|
1148
|
+
if (scimToken && PUBLISHED_TEST_SCIM_TOKENS.has(scimToken)) {
|
|
1149
|
+
throw new Error("Production startup blocked: rotate SCIM_BEARER_TOKEN away from published test defaults.");
|
|
1319
1150
|
}
|
|
1151
|
+
}
|
|
1152
|
+
function assertTokenAuthProductionSecrets(env) {
|
|
1153
|
+
assertPublishedTestTokensRotated(env);
|
|
1320
1154
|
if (!env.TOKEN_HASH_PEPPER?.trim()) {
|
|
1321
1155
|
throw new Error("Production startup blocked: set TOKEN_HASH_PEPPER for API token hashing.");
|
|
1322
1156
|
}
|
|
@@ -1324,11 +1158,11 @@ function assertWorkHubProductionSecrets(env) {
|
|
|
1324
1158
|
throw new Error("Production startup blocked: set API_TOKEN_DEFAULT_EXPIRY_DAYS to enforce token rotation.");
|
|
1325
1159
|
}
|
|
1326
1160
|
}
|
|
1327
|
-
function
|
|
1161
|
+
function assertFeatureProductionSecrets(env) {
|
|
1328
1162
|
if (isEnabled(env.FEATURE_SCIM, false)) {
|
|
1329
|
-
const scimToken = env.SCIM_BEARER_TOKEN ??
|
|
1330
|
-
if (
|
|
1331
|
-
throw new Error("Production startup blocked: rotate SCIM_BEARER_TOKEN away from
|
|
1163
|
+
const scimToken = env.SCIM_BEARER_TOKEN ?? PUBLISHED_TEST_SCIM_BEARER_TOKEN;
|
|
1164
|
+
if (PUBLISHED_TEST_SCIM_TOKENS.has(scimToken) || !env.SCIM_BEARER_TOKEN?.trim()) {
|
|
1165
|
+
throw new Error("Production startup blocked: rotate SCIM_BEARER_TOKEN away from published test defaults.");
|
|
1332
1166
|
}
|
|
1333
1167
|
}
|
|
1334
1168
|
if (isEnabled(env.FEATURE_FIELD_ENCRYPTION, false) && !env.KMS_ENCRYPTION_KEY?.trim()) {
|
|
@@ -1360,10 +1194,9 @@ function assertProductionSecrets(env = process.env) {
|
|
|
1360
1194
|
}
|
|
1361
1195
|
assertAuthDevHeadersDisabled(env);
|
|
1362
1196
|
if (isTokenAuthEnabled(env)) {
|
|
1363
|
-
|
|
1364
|
-
} else {
|
|
1365
|
-
assertSiblingProductionSecrets(env);
|
|
1197
|
+
assertTokenAuthProductionSecrets(env);
|
|
1366
1198
|
}
|
|
1199
|
+
assertFeatureProductionSecrets(env);
|
|
1367
1200
|
const frontendMode = (env.FRONTEND_MODE ?? "api").trim();
|
|
1368
1201
|
if (frontendMode === "server-htmx") {
|
|
1369
1202
|
assertSessionSecret(env);
|
|
@@ -1610,19 +1443,33 @@ class CookieSessionStore {
|
|
|
1610
1443
|
sql() {
|
|
1611
1444
|
return resolveSql(this.sqlSource);
|
|
1612
1445
|
}
|
|
1613
|
-
async create(user) {
|
|
1446
|
+
async create(user, meta = {}) {
|
|
1614
1447
|
const id = randomBytes(32).toString("hex");
|
|
1615
1448
|
const expires = new Date(Date.now() + this.maxAgeSeconds * 1000);
|
|
1616
|
-
await this.sql().unsafe(`INSERT INTO sessions (id, user_id, expires_at
|
|
1617
|
-
|
|
1618
|
-
user.id,
|
|
1619
|
-
expires
|
|
1620
|
-
]);
|
|
1449
|
+
await this.sql().unsafe(`INSERT INTO sessions (id, user_id, expires_at, user_agent, ip_address, last_active_at)
|
|
1450
|
+
VALUES ($1, $2, $3, $4, $5, NOW())`, [id, user.id, expires, meta.userAgent ?? null, meta.ipAddress ?? null]);
|
|
1621
1451
|
return id;
|
|
1622
1452
|
}
|
|
1623
1453
|
async destroy(sessionId) {
|
|
1624
1454
|
await this.sql().unsafe(`DELETE FROM sessions WHERE id = $1`, [sessionId]);
|
|
1625
1455
|
}
|
|
1456
|
+
async destroyOtherSessions(userId, keepSessionId) {
|
|
1457
|
+
await this.sql().unsafe(`DELETE FROM sessions WHERE user_id = $1 AND id <> $2`, [
|
|
1458
|
+
userId,
|
|
1459
|
+
keepSessionId
|
|
1460
|
+
]);
|
|
1461
|
+
}
|
|
1462
|
+
async listForUser(userId) {
|
|
1463
|
+
return this.sql().unsafe(`SELECT id, user_id, user_agent, ip_address, last_active_at, expires_at
|
|
1464
|
+
FROM sessions
|
|
1465
|
+
WHERE user_id = $1 AND expires_at > NOW()
|
|
1466
|
+
ORDER BY last_active_at DESC NULLS LAST, expires_at DESC`, [userId]);
|
|
1467
|
+
}
|
|
1468
|
+
async touch(sessionId) {
|
|
1469
|
+
await this.sql().unsafe(`UPDATE sessions SET last_active_at = NOW() WHERE id = $1`, [
|
|
1470
|
+
sessionId
|
|
1471
|
+
]);
|
|
1472
|
+
}
|
|
1626
1473
|
async read(request) {
|
|
1627
1474
|
const sessionId = this.sessionIdFromRequest(request);
|
|
1628
1475
|
if (!sessionId)
|
|
@@ -1656,8 +1503,8 @@ class CookieSessionAuthManager extends AuthManager2 {
|
|
|
1656
1503
|
super(new CookieSessionGuard(store, mapUser));
|
|
1657
1504
|
this.store = store;
|
|
1658
1505
|
}
|
|
1659
|
-
async signIn(user) {
|
|
1660
|
-
const sessionId = await this.store.create(user);
|
|
1506
|
+
async signIn(user, meta = {}) {
|
|
1507
|
+
const sessionId = await this.store.create(user, meta);
|
|
1661
1508
|
return { sessionId, setCookie: this.store.cookieHeader(user, sessionId) };
|
|
1662
1509
|
}
|
|
1663
1510
|
async signOut(request) {
|
|
@@ -1667,8 +1514,8 @@ class CookieSessionAuthManager extends AuthManager2 {
|
|
|
1667
1514
|
}
|
|
1668
1515
|
return { setCookie: this.store.clearCookieHeader() };
|
|
1669
1516
|
}
|
|
1670
|
-
async signInRedirect(user, location, status = 302) {
|
|
1671
|
-
const { setCookie } = await this.signIn(user);
|
|
1517
|
+
async signInRedirect(user, location, status = 302, meta = {}) {
|
|
1518
|
+
const { setCookie } = await this.signIn(user, meta);
|
|
1672
1519
|
return redirectWithCookie(location, setCookie, status);
|
|
1673
1520
|
}
|
|
1674
1521
|
async signOutRedirect(request, location, status = 302) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getstrata/bootstrap",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.68",
|
|
4
4
|
"description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
|
|
174
174
|
"build:types": "tsc -p tsconfig.types.json && bun ../../scripts/prune-bootstrap-dist-types.ts",
|
|
175
175
|
"prepublishOnly": "bun run build",
|
|
176
|
-
"build:subpaths": "bun build entries/applicationRegistry.ts entries/buildModuleRoutes.ts entries/buildWebModuleRoutes.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/createRoutes.ts entries/createSpaRoutes.ts entries/dependencies.ts entries/discoverModules.ts entries/health.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/listeners/invalidateCacheOnModelWrite.ts entries/membershipService.ts entries/metricsRoutes.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts entries/routeRegistry.ts entries/schedule.ts entries/secretsGuard.ts entries/web/forms.ts entries/web/routing.ts entries/web/server.ts entries/web/session.ts entries/web/slug.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core --external @getstrata/bootstrap --external @getstrata/bootstrap/applicationRegistry --external @getstrata/bootstrap/buildModuleRoutes --external @getstrata/bootstrap/buildWebModuleRoutes --external @getstrata/bootstrap/cache/modelCacheTags --external @getstrata/bootstrap/config --external @getstrata/bootstrap/context --external @getstrata/bootstrap/contracts --external @getstrata/bootstrap/createWebRoutes --external @getstrata/bootstrap/createRoutes --external @getstrata/bootstrap/createSpaRoutes --external @getstrata/bootstrap/dependencies --external @getstrata/bootstrap/discoverModules --external @getstrata/bootstrap/health --external @getstrata/bootstrap/http/securedRouteModelBinding --external @getstrata/bootstrap/httpKernel --external @getstrata/bootstrap/listeners/invalidateCacheOnModelWrite --external @getstrata/bootstrap/membershipService --external @getstrata/bootstrap/metricsRoutes --external @getstrata/bootstrap/queue/defaultJobs --external @getstrata/bootstrap/providers --external @getstrata/bootstrap/providers/view --external @getstrata/bootstrap/routeRegistry --external @getstrata/bootstrap/schedule --external @getstrata/bootstrap/secretsGuard --external @getstrata/bootstrap/web/forms --external @getstrata/bootstrap/web/routing --external @getstrata/bootstrap/web/server --external @getstrata/bootstrap/web/session --external @getstrata/bootstrap/web/slug --external @getstrata/core/auth/accessControl --external @getstrata/core/auth/abilityChecker --external @getstrata/core/auth/authContext --external @getstrata/core/auth/emailVerification --external @getstrata/core/auth/guard --external @getstrata/core/auth/membershipContext --external @getstrata/core/auth/membershipMiddleware --external @getstrata/core/auth/membershipScope --external @getstrata/core/auth/membershipService --external @getstrata/core/auth/oauth/oidcProvider --external @getstrata/core/auth/oauth/providers --external @getstrata/core/auth/oauth/samlProvider --external @getstrata/core/auth/oauth/types --external @getstrata/core/auth/password --external @getstrata/core/auth/intendedUrlCookie --external @getstrata/core/auth/passwordConfirmCookie --external @getstrata/core/auth/policy --external @getstrata/core/auth/scimAuthMiddleware --external @getstrata/core/auth/sessionCookie --external @getstrata/core/auth/sessionGuard --external @getstrata/core/auth/tokenHash --external @getstrata/core/audit/exportAuditLogs --external @getstrata/core/audit/siemFormatter --external @getstrata/core/admin/formatValue --external @getstrata/core/admin/registry --external @getstrata/core/admin/types --external @getstrata/core/cache/tags --external @getstrata/core/cache/createCacheStore --external @getstrata/core/cache/repository --external @getstrata/core/cache/simpleCache --external @getstrata/core/cache/simpleCacheStore --external @getstrata/core/config/envSchema --external @getstrata/core/contracts/serviceTokens --external @getstrata/core/contracts/container --external @getstrata/core/contracts/di --external @getstrata/core/crypto/fieldEncryption --external @getstrata/core/crypto/mfaSecret --external @getstrata/core/database --external @getstrata/core/database/baseRepository --external @getstrata/core/database/bindConnection --external @getstrata/core/database/boundConnection --external @getstrata/core/database/bunSql --external @getstrata/core/database/connection --external @getstrata/core/database/defaultConnection --external @getstrata/core/database/errors --external @getstrata/core/database/factory --external @getstrata/core/database/migrations --external @getstrata/core/database/migrations/types --external @getstrata/core/database/model --external @getstrata/core/database/query --external @getstrata/core/database/relationships --external @getstrata/core/database/repositoryConnection --external @getstrata/core/database/repositoryQuery --external @getstrata/core/database/seeders --external @getstrata/core/database/seeders/types --external @getstrata/core/database/schema --external @getstrata/core/database/table --external @getstrata/core/database/transaction --external @getstrata/core/database/types --external @getstrata/core/database/whereBuilder --external @getstrata/core/errors/http --external @getstrata/core/events --external @getstrata/core/facades --external @getstrata/core/http --external @getstrata/core/http/authMiddleware --external @getstrata/core/http/authorizeMiddleware --external @getstrata/core/http/bodySizeLimitMiddleware --external @getstrata/core/http/clientIp --external @getstrata/core/http/cookies --external @getstrata/core/http/contentNegotiation --external @getstrata/core/http/contentSecurityPolicy --external @getstrata/core/http/conditionalResponse --external @getstrata/core/http/corsMiddleware --external @getstrata/core/http/csrfMiddleware --external @getstrata/core/http/csrfProtection --external @getstrata/core/http/csrfToken --external @getstrata/core/http/etag --external @getstrata/core/http/flashSession --external @getstrata/core/http/flashMiddleware --external @getstrata/core/http/formRequest --external @getstrata/core/http/middleware --external @getstrata/core/http/metricsMiddleware --external @getstrata/core/http/loginThrottleMiddleware --external @getstrata/core/http/memoryThrottleMiddleware --external @getstrata/core/http/pagination --external @getstrata/core/http/parseFormBody --external @getstrata/core/http/parseMultipartUpload --external @getstrata/core/http/requireAbilityMiddleware --external @getstrata/core/http/requireAuthMiddleware --external @getstrata/core/http/requireGlobalAdminMiddleware --external @getstrata/core/http/requireWebAuthMiddleware --external @getstrata/core/http/requireVerifiedMiddleware --external @getstrata/core/http/requirePasswordConfirmMiddleware --external @getstrata/core/http/resources --external @getstrata/core/http/response --external @getstrata/core/http/route --external @getstrata/core/http/routeMiddleware --external @getstrata/core/http/routeModelBinding --external @getstrata/core/http/safeInternalPath --external @getstrata/core/http/signedUrl --external @getstrata/core/http/scimThrottleMiddleware --external @getstrata/core/http/securityHeadersMiddleware --external @getstrata/core/http/securedRouteModelBinding --external @getstrata/core/http/requestMetaContext --external @getstrata/core/http/webErrorResponse --external @getstrata/core/http/webFormRequest --external @getstrata/core/http/throttleMiddleware --external @getstrata/core/http/validation --external @getstrata/core/jobs/
|
|
176
|
+
"build:subpaths": "bun build entries/applicationRegistry.ts entries/buildModuleRoutes.ts entries/buildWebModuleRoutes.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/createRoutes.ts entries/createSpaRoutes.ts entries/dependencies.ts entries/discoverModules.ts entries/health.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/listeners/invalidateCacheOnModelWrite.ts entries/membershipService.ts entries/metricsRoutes.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts entries/routeRegistry.ts entries/schedule.ts entries/secretsGuard.ts entries/web/forms.ts entries/web/routing.ts entries/web/server.ts entries/web/session.ts entries/web/slug.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core --external @getstrata/bootstrap --external @getstrata/bootstrap/applicationRegistry --external @getstrata/bootstrap/buildModuleRoutes --external @getstrata/bootstrap/buildWebModuleRoutes --external @getstrata/bootstrap/cache/modelCacheTags --external @getstrata/bootstrap/config --external @getstrata/bootstrap/context --external @getstrata/bootstrap/contracts --external @getstrata/bootstrap/createWebRoutes --external @getstrata/bootstrap/createRoutes --external @getstrata/bootstrap/createSpaRoutes --external @getstrata/bootstrap/dependencies --external @getstrata/bootstrap/discoverModules --external @getstrata/bootstrap/health --external @getstrata/bootstrap/http/securedRouteModelBinding --external @getstrata/bootstrap/httpKernel --external @getstrata/bootstrap/listeners/invalidateCacheOnModelWrite --external @getstrata/bootstrap/membershipService --external @getstrata/bootstrap/metricsRoutes --external @getstrata/bootstrap/queue/defaultJobs --external @getstrata/bootstrap/providers --external @getstrata/bootstrap/providers/view --external @getstrata/bootstrap/routeRegistry --external @getstrata/bootstrap/schedule --external @getstrata/bootstrap/secretsGuard --external @getstrata/bootstrap/web/forms --external @getstrata/bootstrap/web/routing --external @getstrata/bootstrap/web/server --external @getstrata/bootstrap/web/session --external @getstrata/bootstrap/web/slug --external @getstrata/core/auth/accessControl --external @getstrata/core/auth/abilityChecker --external @getstrata/core/auth/authContext --external @getstrata/core/auth/emailVerification --external @getstrata/core/auth/guard --external @getstrata/core/auth/membershipContext --external @getstrata/core/auth/membershipMiddleware --external @getstrata/core/auth/membershipScope --external @getstrata/core/auth/membershipService --external @getstrata/core/auth/oauth/oidcProvider --external @getstrata/core/auth/oauth/providers --external @getstrata/core/auth/oauth/samlProvider --external @getstrata/core/auth/oauth/types --external @getstrata/core/auth/password --external @getstrata/core/auth/intendedUrlCookie --external @getstrata/core/auth/passwordConfirmCookie --external @getstrata/core/auth/policy --external @getstrata/core/auth/scimAuthMiddleware --external @getstrata/core/auth/sessionCookie --external @getstrata/core/auth/sessionGuard --external @getstrata/core/auth/tokenHash --external @getstrata/core/audit/exportAuditLogs --external @getstrata/core/audit/siemFormatter --external @getstrata/core/admin/formatValue --external @getstrata/core/admin/registry --external @getstrata/core/admin/types --external @getstrata/core/cache/tags --external @getstrata/core/cache/createCacheStore --external @getstrata/core/cache/repository --external @getstrata/core/cache/simpleCache --external @getstrata/core/cache/simpleCacheStore --external @getstrata/core/config/envSchema --external @getstrata/core/contracts/serviceTokens --external @getstrata/core/contracts/container --external @getstrata/core/contracts/di --external @getstrata/core/crypto/fieldEncryption --external @getstrata/core/crypto/mfaSecret --external @getstrata/core/database --external @getstrata/core/database/baseRepository --external @getstrata/core/database/bindConnection --external @getstrata/core/database/boundConnection --external @getstrata/core/database/bunSql --external @getstrata/core/database/connection --external @getstrata/core/database/defaultConnection --external @getstrata/core/database/errors --external @getstrata/core/database/factory --external @getstrata/core/database/migrations --external @getstrata/core/database/migrations/types --external @getstrata/core/database/model --external @getstrata/core/database/query --external @getstrata/core/database/relationships --external @getstrata/core/database/repositoryConnection --external @getstrata/core/database/repositoryQuery --external @getstrata/core/database/seeders --external @getstrata/core/database/seeders/types --external @getstrata/core/database/schema --external @getstrata/core/database/table --external @getstrata/core/database/transaction --external @getstrata/core/database/types --external @getstrata/core/database/whereBuilder --external @getstrata/core/errors/http --external @getstrata/core/events --external @getstrata/core/facades --external @getstrata/core/http --external @getstrata/core/http/authMiddleware --external @getstrata/core/http/authorizeMiddleware --external @getstrata/core/http/bodySizeLimitMiddleware --external @getstrata/core/http/clientIp --external @getstrata/core/http/cookies --external @getstrata/core/http/contentNegotiation --external @getstrata/core/http/contentSecurityPolicy --external @getstrata/core/http/conditionalResponse --external @getstrata/core/http/corsMiddleware --external @getstrata/core/http/csrfMiddleware --external @getstrata/core/http/csrfProtection --external @getstrata/core/http/csrfToken --external @getstrata/core/http/etag --external @getstrata/core/http/flashSession --external @getstrata/core/http/flashMiddleware --external @getstrata/core/http/formRequest --external @getstrata/core/http/middleware --external @getstrata/core/http/metricsMiddleware --external @getstrata/core/http/loginThrottleMiddleware --external @getstrata/core/http/memoryThrottleMiddleware --external @getstrata/core/http/pagination --external @getstrata/core/http/parseFormBody --external @getstrata/core/http/parseMultipartUpload --external @getstrata/core/http/requireAbilityMiddleware --external @getstrata/core/http/requireAuthMiddleware --external @getstrata/core/http/requireGlobalAdminMiddleware --external @getstrata/core/http/requireWebAuthMiddleware --external @getstrata/core/http/requireVerifiedMiddleware --external @getstrata/core/http/requirePasswordConfirmMiddleware --external @getstrata/core/http/resources --external @getstrata/core/http/response --external @getstrata/core/http/route --external @getstrata/core/http/routeMiddleware --external @getstrata/core/http/routeModelBinding --external @getstrata/core/http/safeInternalPath --external @getstrata/core/http/signedUrl --external @getstrata/core/http/scimThrottleMiddleware --external @getstrata/core/http/securityHeadersMiddleware --external @getstrata/core/http/securedRouteModelBinding --external @getstrata/core/http/requestMetaContext --external @getstrata/core/http/webErrorResponse --external @getstrata/core/http/webFormRequest --external @getstrata/core/http/throttleMiddleware --external @getstrata/core/http/validation --external @getstrata/core/jobs/exportAuditLogsJob --external @getstrata/core/jobs/invalidateCacheTagsJob --external @getstrata/core/lifecycle/gracefulShutdown --external @getstrata/core/logging/logger --external @getstrata/core/logging/requestLoggingMiddleware --external @getstrata/core/mail/mailer --external @getstrata/core/mail/markdownMail --external @getstrata/core/mail/markdownMailable --external @getstrata/core/mail/sanitizeMailHtml --external @getstrata/core/media/imageTransform --external @getstrata/core/metrics/prometheus --external @getstrata/core/notifications --external @getstrata/core/openapi/generator --external @getstrata/core/openapi/registeredRoute --external @getstrata/core/openapi/validate --external @getstrata/core/pagination --external @getstrata/core/queue --external @getstrata/core/queue/createAppQueue --external @getstrata/core/queue/failedJobRepository --external @getstrata/core/queue/failedJobService --external @getstrata/core/queue/jobRegistry --external @getstrata/core/queue/jobRunner --external @getstrata/core/queue/queueMetrics --external @getstrata/core/queue/publicQueue --external @getstrata/core/queue/redisQueue --external @getstrata/core/queue/types --external @getstrata/core/runtime/appKeyPrefix --external @getstrata/core/runtime/frontendMode --external @getstrata/core/runtime/applicationRegistry --external @getstrata/core/runtime/asyncContextStore --external @getstrata/core/scheduler/schedule --external @getstrata/core/scheduler/osCron --external @getstrata/core/security/oauthState --external @getstrata/core/security/publicReads --external @getstrata/core/security/recoveryCodes --external @getstrata/core/security/safeFetch --external @getstrata/core/security/safeUrl --external @getstrata/core/security/scimTenantTokens --external @getstrata/core/security/securityEvents --external @getstrata/core/security/stripeWebhook --external @getstrata/core/security/timingSafeCompare --external @getstrata/core/security/tokenExpiry --external @getstrata/core/security/totp --external @getstrata/core/storage/storage --external @getstrata/core/tenant/tenancyConfig --external @getstrata/core/tenant/tenantContext --external @getstrata/core/tenant/tenantDatabaseScope --external @getstrata/core/tenant/databaseTenantContext --external @getstrata/core/tenant/tenantMiddleware --external @getstrata/core/terminal/runShell --external @getstrata/core/tracing/traceContext --external @getstrata/core/tracing/tracingMiddleware --external @getstrata/core/validation/rules --external @getstrata/core/view",
|
|
177
177
|
"build:shims": "true"
|
|
178
178
|
},
|
|
179
179
|
"publishConfig": {
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { RouteHandler } from "@getstrata/core/http/middleware";
|
|
2
|
-
import type { AppDependencies } from "./contracts";
|
|
3
|
-
declare function createScimRoutes(dependencies: AppDependencies): {
|
|
4
|
-
"/scim/v2/ServiceProviderConfig": {
|
|
5
|
-
GET: RouteHandler;
|
|
6
|
-
};
|
|
7
|
-
"/scim/v2/Users": {
|
|
8
|
-
GET: RouteHandler;
|
|
9
|
-
POST: RouteHandler;
|
|
10
|
-
};
|
|
11
|
-
"/scim/v2/Users/:id": {
|
|
12
|
-
GET: RouteHandler;
|
|
13
|
-
PATCH: RouteHandler;
|
|
14
|
-
DELETE: RouteHandler;
|
|
15
|
-
};
|
|
16
|
-
"/scim/v2/Groups": {
|
|
17
|
-
GET: RouteHandler;
|
|
18
|
-
};
|
|
19
|
-
"/scim/v2/Groups/:id": {
|
|
20
|
-
GET: RouteHandler;
|
|
21
|
-
PATCH: RouteHandler;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
export { createScimRoutes };
|