@getstrata/bootstrap 0.2.66 → 0.4.2
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 +45 -10
- package/README.md +10 -10
- package/dist/_.._/_.._/index.html +2 -2
- package/dist/bootstrap/createSpaRoutes.d.ts +9 -2
- package/dist/bootstrap/createWebRoutes.d.ts +7 -3
- package/dist/bootstrap/dogfoodApp.d.ts +7 -0
- package/dist/bootstrap/httpKernel.d.ts +4 -4
- package/dist/bootstrap/public-api.d.ts +2 -1
- package/dist/bootstrap/schemaTarget.d.ts +5 -0
- package/dist/bootstrap/server.d.ts +1 -1
- package/dist/bootstrap/web/index.d.ts +1 -1
- package/dist/bootstrap/web/routing.d.ts +2 -2
- package/dist/bootstrap/web/session.d.ts +18 -3
- package/dist/entries/buildModuleRoutes.js +8 -3
- package/dist/entries/buildWebModuleRoutes.js +8 -3
- package/dist/entries/cache/modelCacheTags.js +6 -1
- package/dist/entries/context.js +52 -166
- package/dist/entries/createRoutes.js +83 -888
- package/dist/entries/createSpaRoutes.js +48 -24
- package/dist/entries/createWebRoutes.js +13 -7
- package/dist/entries/dependencies.js +52 -166
- package/dist/entries/discoverModules.js +6 -1
- package/dist/entries/httpKernel.js +2 -2
- package/dist/entries/listeners/invalidateCacheOnModelWrite.js +6 -1
- package/dist/entries/providers/view.js +5 -160
- package/dist/entries/providers.js +52 -166
- package/dist/entries/secretsGuard.js +13 -8
- package/dist/entries/web/routing.js +4 -3
- package/dist/entries/web/session.js +58 -25
- package/dist/index.js +132 -206
- package/package.json +5 -5
- package/dist/bootstrap/scimRoutes.d.ts +0 -24
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ import { createRequireGlobalAdminMiddleware } from "@getstrata/core/http/require
|
|
|
41
41
|
import { createRequirePasswordConfirmMiddleware } from "@getstrata/core/http/requirePasswordConfirmMiddleware";
|
|
42
42
|
import { createRequireVerifiedMiddleware } from "@getstrata/core/http/requireVerifiedMiddleware";
|
|
43
43
|
import { createRequireWebAuthMiddleware } from "@getstrata/core/http/requireWebAuthMiddleware";
|
|
44
|
-
import { withErrorHandling } from "@getstrata/core/http/response";
|
|
44
|
+
import { withErrorHandling, withJsonErrorHandling } from "@getstrata/core/http/response";
|
|
45
45
|
import { withMiddleware } from "@getstrata/core/http/routeMiddleware";
|
|
46
46
|
import { createSecurityHeadersMiddleware } from "@getstrata/core/http/securityHeadersMiddleware";
|
|
47
47
|
import { createValidateSignatureMiddleware } from "@getstrata/core/http/signedUrl";
|
|
@@ -188,7 +188,7 @@ class HttpKernel {
|
|
|
188
188
|
return withMiddleware(...middleware)(handler);
|
|
189
189
|
}
|
|
190
190
|
wrapApi(handler) {
|
|
191
|
-
return this.wrap(["api", "authenticated"], handler);
|
|
191
|
+
return withJsonErrorHandling(this.wrap(["api", "authenticated"], handler));
|
|
192
192
|
}
|
|
193
193
|
wrapWeb(handler) {
|
|
194
194
|
return withErrorHandling(this.wrap("web", handler));
|
|
@@ -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();
|
|
@@ -522,17 +527,19 @@ import {
|
|
|
522
527
|
} from "@getstrata/core/contracts/di";
|
|
523
528
|
|
|
524
529
|
// ../../src/bootstrap/providers/auth.ts
|
|
530
|
+
import { BasicAuthGuard } from "@getstrata/core/auth/basicAuthGuard";
|
|
525
531
|
import {
|
|
526
532
|
AuthManager,
|
|
527
533
|
CompositeGuard,
|
|
528
534
|
DatabaseTokenGuard,
|
|
529
535
|
GuestGuard
|
|
530
536
|
} from "@getstrata/core/auth/guard";
|
|
537
|
+
import { JwtGuard } from "@getstrata/core/auth/jwtGuard";
|
|
531
538
|
import { SessionGuard } from "@getstrata/core/auth/sessionGuard";
|
|
532
539
|
|
|
533
540
|
// ../../src/config/auth.ts
|
|
534
541
|
var authConfig = {
|
|
535
|
-
allowDevHeaders:
|
|
542
|
+
allowDevHeaders: process.env.AUTH_DEV_HEADERS === "true",
|
|
536
543
|
tokenDefaultAbilities: ["*"]
|
|
537
544
|
};
|
|
538
545
|
|
|
@@ -541,11 +548,22 @@ var authProvider = {
|
|
|
541
548
|
name: "core.auth",
|
|
542
549
|
register({ container, config }) {
|
|
543
550
|
config.set("auth.allowDevHeaders", authConfig.allowDevHeaders);
|
|
544
|
-
const
|
|
551
|
+
const apiGuard = new DatabaseTokenGuard(container);
|
|
552
|
+
const sessionGuard = new SessionGuard(container);
|
|
553
|
+
const jwtGuard = new JwtGuard;
|
|
554
|
+
const basicGuard = new BasicAuthGuard(container);
|
|
555
|
+
const guards = [apiGuard, jwtGuard, basicGuard, sessionGuard];
|
|
545
556
|
if (authConfig.allowDevHeaders) {
|
|
546
557
|
guards.push(new GuestGuard);
|
|
547
558
|
}
|
|
548
|
-
|
|
559
|
+
const auth = new AuthManager(new CompositeGuard(guards));
|
|
560
|
+
auth.registerGuard("api", apiGuard);
|
|
561
|
+
auth.registerGuard("access_token", apiGuard);
|
|
562
|
+
auth.registerGuard("jwt", jwtGuard);
|
|
563
|
+
auth.registerGuard("basic", basicGuard);
|
|
564
|
+
auth.registerGuard("web", sessionGuard);
|
|
565
|
+
auth.registerGuard("session", sessionGuard);
|
|
566
|
+
container.set(CORE_AUTH_TOKEN, auth);
|
|
549
567
|
}
|
|
550
568
|
};
|
|
551
569
|
var auth_default = authProvider;
|
|
@@ -606,8 +624,12 @@ var queueConfig = {
|
|
|
606
624
|
};
|
|
607
625
|
// ../../src/bootstrap/env.ts
|
|
608
626
|
import { defineEnvSchema } from "@getstrata/core/config/envSchema";
|
|
627
|
+
import { DEFAULT_SPA_PREFIX, FRONTEND_MODE_PATTERN } from "@getstrata/core/runtime/frontendMode";
|
|
609
628
|
var appEnvSchema = defineEnvSchema({
|
|
610
|
-
DATABASE_URL: {
|
|
629
|
+
DATABASE_URL: {
|
|
630
|
+
required: true,
|
|
631
|
+
pattern: /^(postgres(ql)?|mysql|sqlite):\/\//i
|
|
632
|
+
},
|
|
611
633
|
PORT: {
|
|
612
634
|
integer: true,
|
|
613
635
|
minimum: 1,
|
|
@@ -635,9 +657,21 @@ var appEnvSchema = defineEnvSchema({
|
|
|
635
657
|
pattern: /^(sync|async|redis)$/
|
|
636
658
|
},
|
|
637
659
|
AUTH_DEV_HEADERS: {
|
|
638
|
-
default: "
|
|
660
|
+
default: "false",
|
|
639
661
|
pattern: /^(true|false|0|1)$/
|
|
640
662
|
},
|
|
663
|
+
DB_CONNECTION: {
|
|
664
|
+
default: "",
|
|
665
|
+
pattern: /^(pgsql|postgres|postgresql|mysql|mariadb|sqlite)?$/i
|
|
666
|
+
},
|
|
667
|
+
AUTH_DEFAULT_GUARD: {
|
|
668
|
+
default: "web"
|
|
669
|
+
},
|
|
670
|
+
JWT_TTL_SECONDS: {
|
|
671
|
+
integer: true,
|
|
672
|
+
minimum: 60,
|
|
673
|
+
default: "3600"
|
|
674
|
+
},
|
|
641
675
|
APP_ENV: {
|
|
642
676
|
default: "local"
|
|
643
677
|
},
|
|
@@ -647,6 +681,13 @@ var appEnvSchema = defineEnvSchema({
|
|
|
647
681
|
APP_URL: {
|
|
648
682
|
default: "http://localhost:3000"
|
|
649
683
|
},
|
|
684
|
+
FRONTEND_MODE: {
|
|
685
|
+
default: "api",
|
|
686
|
+
pattern: FRONTEND_MODE_PATTERN
|
|
687
|
+
},
|
|
688
|
+
SPA_PREFIX: {
|
|
689
|
+
default: DEFAULT_SPA_PREFIX
|
|
690
|
+
},
|
|
650
691
|
API_PREFIX: {
|
|
651
692
|
default: "/api/v1"
|
|
652
693
|
},
|
|
@@ -871,7 +912,6 @@ var storageProvider = {
|
|
|
871
912
|
var storage_default = storageProvider;
|
|
872
913
|
|
|
873
914
|
// ../../src/bootstrap/providers/view.ts
|
|
874
|
-
import { resolveMembershipLookup } from "@getstrata/core/auth/membershipContext";
|
|
875
915
|
import { currentRequestMeta } from "@getstrata/core/http/requestMetaContext";
|
|
876
916
|
import { appDisplayName } from "@getstrata/core/runtime/appKeyPrefix";
|
|
877
917
|
import { isViewsEnabled as isViewsEnabled2 } from "@getstrata/core/runtime/frontendMode";
|
|
@@ -883,148 +923,6 @@ import {
|
|
|
883
923
|
errorTemplateName,
|
|
884
924
|
resolveWebLayoutData
|
|
885
925
|
} 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
926
|
var CORE_VIEW_TOKEN = "core.view";
|
|
1029
927
|
var VIEW_DIRECTORY_CONFIG_KEY = "view.directory";
|
|
1030
928
|
var viewProvider = {
|
|
@@ -1038,23 +936,11 @@ var viewProvider = {
|
|
|
1038
936
|
const engine = new EtaViewEngine(viewsDirectory, (request) => resolveWebLayoutData(container, request ?? currentRequestMeta().request));
|
|
1039
937
|
container.set(CORE_VIEW_TOKEN, engine);
|
|
1040
938
|
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
|
-
}
|
|
939
|
+
extra: async () => ({
|
|
940
|
+
appName: appDisplayName(),
|
|
941
|
+
currentOrganization: null,
|
|
942
|
+
organizations: []
|
|
943
|
+
})
|
|
1058
944
|
});
|
|
1059
945
|
configureWebErrorView({
|
|
1060
946
|
render: async (input) => engine.render(errorTemplateName(input.status), {
|
|
@@ -1118,9 +1004,10 @@ import { notFoundHtmlResponse } from "@getstrata/core/view";
|
|
|
1118
1004
|
function registerRoute(method, path, middleware) {
|
|
1119
1005
|
routeRegistry.register({ method, path, middleware });
|
|
1120
1006
|
}
|
|
1121
|
-
function createWebRoutes(dependencies) {
|
|
1007
|
+
function createWebRoutes(dependencies, options = {}) {
|
|
1122
1008
|
const wrappedRoutes = buildWebModuleRoutes(dependencies, {
|
|
1123
|
-
clearRegistry: false
|
|
1009
|
+
clearRegistry: false,
|
|
1010
|
+
modules: options.modules
|
|
1124
1011
|
});
|
|
1125
1012
|
registerRoute("GET", "/", ["global", "web"]);
|
|
1126
1013
|
wrappedRoutes["/assets/*"] = async (request) => {
|
|
@@ -1136,12 +1023,12 @@ function createWebRoutes(dependencies) {
|
|
|
1136
1023
|
registerRoute("GET", "/assets/*", ["global", "web"]);
|
|
1137
1024
|
return wrappedRoutes;
|
|
1138
1025
|
}
|
|
1139
|
-
function mergeWebRoutes(dependencies, routes) {
|
|
1026
|
+
function mergeWebRoutes(dependencies, routes, options = {}) {
|
|
1140
1027
|
if (!isViewsEnabled3()) {
|
|
1141
1028
|
return routes;
|
|
1142
1029
|
}
|
|
1143
1030
|
return {
|
|
1144
|
-
...createWebRoutes(dependencies),
|
|
1031
|
+
...createWebRoutes(dependencies, options),
|
|
1145
1032
|
...routes
|
|
1146
1033
|
};
|
|
1147
1034
|
}
|
|
@@ -1252,15 +1139,21 @@ import {
|
|
|
1252
1139
|
// ../../src/bootstrap/membershipService.ts
|
|
1253
1140
|
import { resolveMembershipService } from "@getstrata/core/auth/membershipService";
|
|
1254
1141
|
// ../../src/bootstrap/secretsGuard.ts
|
|
1255
|
-
|
|
1256
|
-
var
|
|
1257
|
-
var
|
|
1142
|
+
import { isViewsMode, parseFrontendMode } from "@getstrata/core/runtime/frontendMode";
|
|
1143
|
+
var PUBLISHED_TEST_ADMIN_API_TOKEN = "strata-admin-test-token";
|
|
1144
|
+
var PUBLISHED_TEST_MEMBER_API_TOKEN = "strata-member-test-token";
|
|
1145
|
+
var PUBLISHED_TEST_SCIM_BEARER_TOKEN = "strata-scim-test-token";
|
|
1258
1146
|
var MIN_SESSION_SECRET_LENGTH = 32;
|
|
1259
1147
|
var PUBLISHED_TEST_TOKENS = new Set([
|
|
1260
1148
|
PUBLISHED_TEST_ADMIN_API_TOKEN,
|
|
1261
|
-
PUBLISHED_TEST_MEMBER_API_TOKEN
|
|
1149
|
+
PUBLISHED_TEST_MEMBER_API_TOKEN,
|
|
1150
|
+
"workhub-admin-test-token",
|
|
1151
|
+
"workhub-member-test-token"
|
|
1152
|
+
]);
|
|
1153
|
+
var PUBLISHED_TEST_SCIM_TOKENS = new Set([
|
|
1154
|
+
PUBLISHED_TEST_SCIM_BEARER_TOKEN,
|
|
1155
|
+
"workhub-scim-test-token"
|
|
1262
1156
|
]);
|
|
1263
|
-
var PUBLISHED_TEST_SCIM_TOKENS = new Set([PUBLISHED_TEST_SCIM_BEARER_TOKEN]);
|
|
1264
1157
|
function isEnabled(value, defaultEnabled) {
|
|
1265
1158
|
if (value === undefined) {
|
|
1266
1159
|
return defaultEnabled;
|
|
@@ -1284,7 +1177,7 @@ function assertAuthDevHeadersDisabled(env) {
|
|
|
1284
1177
|
function assertSessionSecret(env) {
|
|
1285
1178
|
const secret = env.SESSION_SECRET?.trim() ?? "";
|
|
1286
1179
|
if (secret.length < MIN_SESSION_SECRET_LENGTH) {
|
|
1287
|
-
throw new Error("Production startup blocked: set SESSION_SECRET when FRONTEND_MODE=server-htmx (32+ characters).");
|
|
1180
|
+
throw new Error("Production startup blocked: set SESSION_SECRET when FRONTEND_MODE=server-htmx or hybrid (32+ characters).");
|
|
1288
1181
|
}
|
|
1289
1182
|
}
|
|
1290
1183
|
function assertPublishedTestTokensRotated(env) {
|
|
@@ -1346,8 +1239,7 @@ function assertProductionSecrets(env = process.env) {
|
|
|
1346
1239
|
assertTokenAuthProductionSecrets(env);
|
|
1347
1240
|
}
|
|
1348
1241
|
assertFeatureProductionSecrets(env);
|
|
1349
|
-
|
|
1350
|
-
if (frontendMode === "server-htmx") {
|
|
1242
|
+
if (isViewsMode(parseFrontendMode(env.FRONTEND_MODE))) {
|
|
1351
1243
|
assertSessionSecret(env);
|
|
1352
1244
|
}
|
|
1353
1245
|
}
|
|
@@ -1384,6 +1276,7 @@ async function parseFormBody(request) {
|
|
|
1384
1276
|
return { fields, files };
|
|
1385
1277
|
}
|
|
1386
1278
|
// ../../src/bootstrap/web/routing.ts
|
|
1279
|
+
import { requestPrefersJson } from "@getstrata/core/http/contentNegotiation";
|
|
1387
1280
|
import { withErrorHandling as withErrorHandling2 } from "@getstrata/core/http/response";
|
|
1388
1281
|
function routeParams(request) {
|
|
1389
1282
|
const normalized = {};
|
|
@@ -1419,7 +1312,7 @@ function wrapWebThrottle(kernel, scope, handler, onThrottled) {
|
|
|
1419
1312
|
const throttled = scope === "login" ? kernel.wrapLogin(handler) : kernel.wrapRegister(handler);
|
|
1420
1313
|
return async (request) => {
|
|
1421
1314
|
const response = await throttled(request);
|
|
1422
|
-
if (response.status === 429) {
|
|
1315
|
+
if (response.status === 429 && !requestPrefersJson(request)) {
|
|
1423
1316
|
return onThrottled(request);
|
|
1424
1317
|
}
|
|
1425
1318
|
return response;
|
|
@@ -1498,11 +1391,19 @@ function createWebServer(options) {
|
|
|
1498
1391
|
});
|
|
1499
1392
|
}
|
|
1500
1393
|
// ../../src/bootstrap/web/session.ts
|
|
1501
|
-
import {
|
|
1394
|
+
import { createHmac, randomBytes } from "crypto";
|
|
1502
1395
|
import { AuthManager as AuthManager2 } from "@getstrata/core/auth/guard";
|
|
1503
1396
|
import { getBoundDatabaseConnection as getBoundDatabaseConnection2 } from "@getstrata/core/database/boundConnection";
|
|
1504
1397
|
import { getDefaultDatabasePool as getDefaultDatabasePool2 } from "@getstrata/core/database/defaultConnection";
|
|
1398
|
+
import { currentSqlDialect } from "@getstrata/core/database/dialect";
|
|
1505
1399
|
import { readRequestCookie } from "@getstrata/core/http/cookies";
|
|
1400
|
+
import { timingSafeCompareString } from "@getstrata/core/security/timingSafeCompare";
|
|
1401
|
+
function sqlPlaceholder(index) {
|
|
1402
|
+
return currentSqlDialect().placeholder(index);
|
|
1403
|
+
}
|
|
1404
|
+
function sqlNow() {
|
|
1405
|
+
return currentSqlDialect().nowExpression();
|
|
1406
|
+
}
|
|
1506
1407
|
function isSqlClient(value) {
|
|
1507
1408
|
return typeof value.unsafe === "function";
|
|
1508
1409
|
}
|
|
@@ -1525,22 +1426,34 @@ function defaultMapSessionUser(user) {
|
|
|
1525
1426
|
role: user.is_admin ? "admin" : "member"
|
|
1526
1427
|
};
|
|
1527
1428
|
}
|
|
1429
|
+
function sessionDisplayName(row, email) {
|
|
1430
|
+
if (typeof row.name === "string" && row.name.trim() !== "") {
|
|
1431
|
+
return row.name;
|
|
1432
|
+
}
|
|
1433
|
+
const first = typeof row.first_name === "string" ? row.first_name.trim() : "";
|
|
1434
|
+
const last = typeof row.last_name === "string" ? row.last_name.trim() : "";
|
|
1435
|
+
const composed = `${first} ${last}`.trim();
|
|
1436
|
+
return composed || email;
|
|
1437
|
+
}
|
|
1438
|
+
function mapSessionUserRow(row) {
|
|
1439
|
+
const email = typeof row.email === "string" ? row.email : "";
|
|
1440
|
+
return {
|
|
1441
|
+
id: Number(row.user_id ?? row.id),
|
|
1442
|
+
name: sessionDisplayName(row, email),
|
|
1443
|
+
email,
|
|
1444
|
+
learn_subscriber: Boolean(row.learn_subscriber),
|
|
1445
|
+
is_admin: Boolean(row.is_admin)
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1528
1448
|
async function defaultLoadSessionUser(sql, sessionId) {
|
|
1529
|
-
const rows = await sql.unsafe(`SELECT s.
|
|
1530
|
-
COALESCE(u.is_admin, false) AS is_admin
|
|
1449
|
+
const rows = await sql.unsafe(`SELECT s.user_id, s.expires_at, u.*
|
|
1531
1450
|
FROM sessions s
|
|
1532
1451
|
INNER JOIN users u ON u.id = s.user_id
|
|
1533
|
-
WHERE s.id = $1 AND s.expires_at >
|
|
1452
|
+
WHERE s.id = ${sqlPlaceholder(1)} AND s.expires_at > ${sqlNow()}`, [sessionId]);
|
|
1534
1453
|
const row = rows[0];
|
|
1535
1454
|
if (!row)
|
|
1536
1455
|
return null;
|
|
1537
|
-
return
|
|
1538
|
-
id: row.user_id,
|
|
1539
|
-
name: row.name,
|
|
1540
|
-
email: row.email,
|
|
1541
|
-
learn_subscriber: row.learn_subscriber,
|
|
1542
|
-
is_admin: row.is_admin
|
|
1543
|
-
};
|
|
1456
|
+
return mapSessionUserRow(row);
|
|
1544
1457
|
}
|
|
1545
1458
|
function redirectWithCookie(location, setCookie, status) {
|
|
1546
1459
|
return new Response(null, {
|
|
@@ -1578,7 +1491,7 @@ class CookieSessionStore {
|
|
|
1578
1491
|
if (!raw)
|
|
1579
1492
|
return null;
|
|
1580
1493
|
const [sessionId, signature] = raw.split(".");
|
|
1581
|
-
if (!sessionId || !signature || signature
|
|
1494
|
+
if (!sessionId || !signature || !timingSafeCompareString(signature, this.sign(sessionId))) {
|
|
1582
1495
|
return null;
|
|
1583
1496
|
}
|
|
1584
1497
|
return sessionId;
|
|
@@ -1592,18 +1505,28 @@ class CookieSessionStore {
|
|
|
1592
1505
|
sql() {
|
|
1593
1506
|
return resolveSql(this.sqlSource);
|
|
1594
1507
|
}
|
|
1595
|
-
async create(user) {
|
|
1508
|
+
async create(user, meta = {}) {
|
|
1596
1509
|
const id = randomBytes(32).toString("hex");
|
|
1597
1510
|
const expires = new Date(Date.now() + this.maxAgeSeconds * 1000);
|
|
1598
|
-
await this.sql().unsafe(`INSERT INTO sessions (id, user_id, expires_at
|
|
1599
|
-
|
|
1600
|
-
user.id,
|
|
1601
|
-
expires
|
|
1602
|
-
]);
|
|
1511
|
+
await this.sql().unsafe(`INSERT INTO sessions (id, user_id, expires_at, user_agent, ip_address, last_active_at)
|
|
1512
|
+
VALUES (${sqlPlaceholder(1)}, ${sqlPlaceholder(2)}, ${sqlPlaceholder(3)}, ${sqlPlaceholder(4)}, ${sqlPlaceholder(5)}, ${sqlNow()})`, [id, user.id, expires, meta.userAgent ?? null, meta.ipAddress ?? null]);
|
|
1603
1513
|
return id;
|
|
1604
1514
|
}
|
|
1605
1515
|
async destroy(sessionId) {
|
|
1606
|
-
await this.sql().unsafe(`DELETE FROM sessions WHERE id = $1`, [sessionId]);
|
|
1516
|
+
await this.sql().unsafe(`DELETE FROM sessions WHERE id = ${sqlPlaceholder(1)}`, [sessionId]);
|
|
1517
|
+
}
|
|
1518
|
+
async destroyOtherSessions(userId, keepSessionId) {
|
|
1519
|
+
await this.sql().unsafe(`DELETE FROM sessions WHERE user_id = ${sqlPlaceholder(1)} AND id <> ${sqlPlaceholder(2)}`, [userId, keepSessionId]);
|
|
1520
|
+
}
|
|
1521
|
+
async listForUser(userId) {
|
|
1522
|
+
const dialect = currentSqlDialect();
|
|
1523
|
+
return this.sql().unsafe(`SELECT id, user_id, user_agent, ip_address, last_active_at, expires_at
|
|
1524
|
+
FROM sessions
|
|
1525
|
+
WHERE user_id = ${dialect.placeholder(1)} AND expires_at > ${dialect.nowExpression()}
|
|
1526
|
+
ORDER BY last_active_at DESC${dialect.nullsLastSuffix()}, expires_at DESC`, [userId]);
|
|
1527
|
+
}
|
|
1528
|
+
async touch(sessionId) {
|
|
1529
|
+
await this.sql().unsafe(`UPDATE sessions SET last_active_at = ${sqlNow()} WHERE id = ${sqlPlaceholder(1)}`, [sessionId]);
|
|
1607
1530
|
}
|
|
1608
1531
|
async read(request) {
|
|
1609
1532
|
const sessionId = this.sessionIdFromRequest(request);
|
|
@@ -1612,7 +1535,7 @@ class CookieSessionStore {
|
|
|
1612
1535
|
return this.loadSessionUser(this.sql(), sessionId);
|
|
1613
1536
|
}
|
|
1614
1537
|
sign(value) {
|
|
1615
|
-
return
|
|
1538
|
+
return createHmac("sha256", this.secret).update(value).digest("hex").slice(0, 32);
|
|
1616
1539
|
}
|
|
1617
1540
|
}
|
|
1618
1541
|
|
|
@@ -1635,11 +1558,14 @@ class CookieSessionGuard {
|
|
|
1635
1558
|
class CookieSessionAuthManager extends AuthManager2 {
|
|
1636
1559
|
store;
|
|
1637
1560
|
constructor(store, mapUser = defaultMapSessionUser) {
|
|
1638
|
-
|
|
1561
|
+
const guard = new CookieSessionGuard(store, mapUser);
|
|
1562
|
+
super(guard);
|
|
1639
1563
|
this.store = store;
|
|
1564
|
+
this.registerGuard("web", guard);
|
|
1565
|
+
this.registerGuard("session", guard);
|
|
1640
1566
|
}
|
|
1641
|
-
async signIn(user) {
|
|
1642
|
-
const sessionId = await this.store.create(user);
|
|
1567
|
+
async signIn(user, meta = {}) {
|
|
1568
|
+
const sessionId = await this.store.create(user, meta);
|
|
1643
1569
|
return { sessionId, setCookie: this.store.cookieHeader(user, sessionId) };
|
|
1644
1570
|
}
|
|
1645
1571
|
async signOut(request) {
|
|
@@ -1649,8 +1575,8 @@ class CookieSessionAuthManager extends AuthManager2 {
|
|
|
1649
1575
|
}
|
|
1650
1576
|
return { setCookie: this.store.clearCookieHeader() };
|
|
1651
1577
|
}
|
|
1652
|
-
async signInRedirect(user, location, status = 302) {
|
|
1653
|
-
const { setCookie } = await this.signIn(user);
|
|
1578
|
+
async signInRedirect(user, location, status = 302, meta = {}) {
|
|
1579
|
+
const { setCookie } = await this.signIn(user, meta);
|
|
1654
1580
|
return redirectWithCookie(location, setCookie, status);
|
|
1655
1581
|
}
|
|
1656
1582
|
async signOutRedirect(request, location, status = 302) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getstrata/bootstrap",
|
|
3
|
-
"version": "0.2
|
|
4
|
-
"description": "Strata application bootstrap
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Strata application bootstrap: HttpKernel, DI, web session helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -170,17 +170,17 @@
|
|
|
170
170
|
],
|
|
171
171
|
"scripts": {
|
|
172
172
|
"build": "bun run build:bundle && bun run build:shims && bun run build:subpaths && bun run build:types",
|
|
173
|
-
"build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
|
|
173
|
+
"build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external mysql2 --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/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",
|
|
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 mysql2 --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/jwt --external @getstrata/core/auth/jwtGuard --external @getstrata/core/auth/basicAuthGuard --external @getstrata/core/auth/tokenAbilityChecker --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/connectionContext --external @getstrata/core/database/defaultConnection --external @getstrata/core/database/dialect --external @getstrata/core/database/mysqlConnection --external @getstrata/core/database/namedConnections --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/sqliteConnection --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/statelessAuth --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": {
|
|
180
180
|
"access": "public"
|
|
181
181
|
},
|
|
182
182
|
"peerDependencies": {
|
|
183
|
-
"@getstrata/core": "^0.
|
|
183
|
+
"@getstrata/core": "^0.7.2",
|
|
184
184
|
"typescript": "^5.9.0"
|
|
185
185
|
}
|
|
186
186
|
}
|
|
@@ -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 };
|