@getstrata/core 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/contracts.d.ts +2 -0
- package/dist/core/auth/membershipService.d.ts +5 -1
- package/dist/core/database/baseRepository.d.ts +6 -1
- package/dist/core/database/connectionContext.d.ts +2 -1
- package/dist/core/database/defaultConnection.d.ts +6 -0
- package/dist/core/database/queryProxy.d.ts +3 -0
- package/dist/core/database/repositoryConnection.d.ts +3 -3
- package/dist/core/jobs/dispatchWebhookJob.d.ts +0 -1
- package/dist/core/security/safeFetch.d.ts +2 -0
- package/dist/core/security/safeUrl.d.ts +16 -1
- package/dist/core/tenant/tenantDatabaseScope.d.ts +2 -1
- package/dist/db/connection/index.d.ts +1 -1
- package/dist/entries/auth/accessControl.js +1 -113
- package/dist/entries/auth/authContext.js +1 -15
- package/dist/entries/auth/guard.js +1 -3044
- package/dist/entries/auth/membershipContext.js +1 -276
- package/dist/entries/auth/membershipScope.js +1 -390
- package/dist/entries/auth/membershipService.js +1 -480
- package/dist/entries/auth/policy.js +1 -134
- package/dist/entries/database.js +1 -2398
- package/dist/entries/http/csrfToken.js +0 -6
- package/dist/entries/http/middleware.js +1 -68
- package/dist/entries/http/requestMetaContext.js +1 -18
- package/dist/entries/http/webErrorResponse.js +94 -563
- package/dist/entries/http/webFormRequest.js +0 -131
- package/dist/entries/http.js +1 -4091
- package/dist/entries/jobs/dispatchWebhookJob.js +109 -102
- package/dist/entries/queue/createAppQueue.js +111 -631
- package/dist/entries/queue/jobRunner.js +0 -3
- package/dist/entries/queue/publicQueue.js +45 -546
- package/dist/entries/queue/queueMetrics.js +111 -631
- package/dist/entries/security/safeUrl.js +29 -0
- package/dist/entries/security/securityEvents.js +1 -41
- package/dist/entries/tenant/tenantContext.js +1 -30
- package/dist/entries/tenant/tenantMiddleware.js +1 -312
- package/dist/entries/tracing/traceContext.js +1 -15
- package/dist/entries/view.js +94 -563
- package/dist/framework/public-api.d.ts +29 -6
- package/dist/index.js +2125 -2000
- package/dist/modules/user/repository.d.ts +1 -0
- package/package.json +6 -5
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StorageManager } from "../core/storage/storage";
|
|
1
2
|
import type { CacheLike } from "../types/services";
|
|
2
3
|
type CachedJson = <T>(cacheKey: string, loader: () => Promise<T>, tags?: string[], request?: Request) => Promise<Response>;
|
|
3
4
|
type AppRouteMap = Record<string, any>;
|
|
@@ -23,6 +24,7 @@ declare class ConfigStore {
|
|
|
23
24
|
interface AppDependencies {
|
|
24
25
|
container: ServiceContainer;
|
|
25
26
|
cache: CacheLike;
|
|
27
|
+
storage: StorageManager;
|
|
26
28
|
}
|
|
27
29
|
type MutableAppDependencies = Partial<Omit<AppDependencies, "container">> & Pick<AppDependencies, "container">;
|
|
28
30
|
interface ProviderContext {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { OrganizationMemberRole } from "../../modules/organization/memberTypes";
|
|
2
2
|
import { type AuthUser } from "./authContext";
|
|
3
|
+
import { membershipRepository as defaultMembershipRepository } from "./membershipContext";
|
|
4
|
+
type MembershipRepositoryLike = Pick<typeof defaultMembershipRepository, "listForUser" | "findMembership" | "listForOrganization" | "addMember" | "removeMember">;
|
|
3
5
|
declare class MembershipService {
|
|
4
|
-
|
|
6
|
+
private readonly members;
|
|
7
|
+
constructor(members?: MembershipRepositoryLike);
|
|
5
8
|
listOrganizationIdsForUser(userId: number): Promise<number[]>;
|
|
6
9
|
getOrgRole(userId: number, organizationId: number): Promise<OrganizationMemberRole | null>;
|
|
7
10
|
requireOrgAccess(organizationId: number, minimumRole?: OrganizationMemberRole, user?: AuthUser | null): Promise<OrganizationMemberRole>;
|
|
@@ -16,5 +19,6 @@ declare class MembershipService {
|
|
|
16
19
|
removeMember(organizationId: number, userId: number): Promise<boolean>;
|
|
17
20
|
}
|
|
18
21
|
declare function resolveMembershipService(): MembershipService;
|
|
22
|
+
export type { MembershipRepositoryLike };
|
|
19
23
|
export default MembershipService;
|
|
20
24
|
export { resolveMembershipService };
|
|
@@ -9,6 +9,11 @@ type ExtendedQueryOptions<TEntity extends object> = QueryOptions<TEntity> & {
|
|
|
9
9
|
};
|
|
10
10
|
interface DatabaseConnection {
|
|
11
11
|
unsafe<T>(query: string, params?: readonly unknown[]): Promise<T[]>;
|
|
12
|
+
begin?<T>(callback: (transaction: DatabaseConnection) => Promise<T>): Promise<T>;
|
|
13
|
+
close?(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
interface SqlDatabaseConnection extends DatabaseConnection {
|
|
16
|
+
(strings: TemplateStringsArray, ...values: unknown[]): Promise<unknown[]>;
|
|
12
17
|
}
|
|
13
18
|
type ErrorFactory<TValue> = (value: TValue) => Error;
|
|
14
19
|
declare class BaseRepository<TEntity extends object, PrimaryKey extends keyof TEntity & string> {
|
|
@@ -59,4 +64,4 @@ declare class BaseRepository<TEntity extends object, PrimaryKey extends keyof TE
|
|
|
59
64
|
loadMorphToForChildren<TChild extends object, TParent extends object, MorphTypeKey extends keyof TChild & string, MorphIdKey extends keyof TChild & string, OwnerKey extends keyof TParent & string>(children: readonly TChild[], relation: MorphToRelation<TChild, MorphTypeKey, MorphIdKey>, repositoriesByType: ReadonlyMap<string, BaseRepository<TParent, OwnerKey>>, options?: Omit<QueryOptions<TParent>, "where">): Promise<Map<TChild[MorphIdKey], TParent>>;
|
|
60
65
|
}
|
|
61
66
|
export default BaseRepository;
|
|
62
|
-
export type { DatabaseConnection };
|
|
67
|
+
export type { DatabaseConnection, SqlDatabaseConnection };
|
|
@@ -3,5 +3,6 @@ type ActiveDatabaseHandle = {
|
|
|
3
3
|
};
|
|
4
4
|
declare function runWithDatabaseConnection<T>(connection: ActiveDatabaseHandle, callback: () => T | Promise<T>): T | Promise<T>;
|
|
5
5
|
declare function getActiveDatabaseConnection<T extends ActiveDatabaseHandle>(fallback: T): T;
|
|
6
|
+
declare function hasActiveDatabaseConnection(): boolean;
|
|
6
7
|
export type { ActiveDatabaseHandle };
|
|
7
|
-
export { getActiveDatabaseConnection, runWithDatabaseConnection };
|
|
8
|
+
export { getActiveDatabaseConnection, hasActiveDatabaseConnection, runWithDatabaseConnection };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SqlDatabaseConnection } from "./baseRepository";
|
|
2
|
+
declare function registerDefaultDatabasePool(connection: SqlDatabaseConnection): void;
|
|
3
|
+
declare function getDefaultDatabasePool(): SqlDatabaseConnection;
|
|
4
|
+
declare function getDefaultDatabaseQuery(): SqlDatabaseConnection;
|
|
5
|
+
declare function resetDefaultDatabasePoolForTests(): void;
|
|
6
|
+
export { getDefaultDatabasePool, getDefaultDatabaseQuery, registerDefaultDatabasePool, resetDefaultDatabasePoolForTests, };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare function resolveRepositoryConnection():
|
|
3
|
-
declare const repositoryConnection:
|
|
1
|
+
import type { SqlDatabaseConnection } from "./baseRepository";
|
|
2
|
+
declare function resolveRepositoryConnection(): SqlDatabaseConnection;
|
|
3
|
+
declare const repositoryConnection: SqlDatabaseConnection;
|
|
4
4
|
export { repositoryConnection, resolveRepositoryConnection };
|
|
@@ -5,7 +5,6 @@ interface DispatchWebhookPayload {
|
|
|
5
5
|
payload: Record<string, unknown>;
|
|
6
6
|
}
|
|
7
7
|
declare class DispatchWebhookJob extends Job<DispatchWebhookPayload> {
|
|
8
|
-
constructor();
|
|
9
8
|
readonly maxAttempts = 3;
|
|
10
9
|
readonly backoffMs = 2000;
|
|
11
10
|
handle(payload: DispatchWebhookPayload): Promise<void>;
|
|
@@ -2,6 +2,8 @@ declare const DEFAULT_FETCH_TIMEOUT_MS = 10000;
|
|
|
2
2
|
interface SafeFetchOptions {
|
|
3
3
|
timeoutMs?: number;
|
|
4
4
|
maxRedirects?: number;
|
|
5
|
+
allowHttp?: boolean;
|
|
6
|
+
resolveDns?: boolean;
|
|
5
7
|
}
|
|
6
8
|
declare function safeFetch(input: string, init?: RequestInit, options?: SafeFetchOptions): Promise<Response>;
|
|
7
9
|
export type { SafeFetchOptions };
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
type DnsLookupResult = {
|
|
2
|
+
address: string;
|
|
3
|
+
family: number;
|
|
4
|
+
};
|
|
5
|
+
type DnsLookup = (hostname: string, options: {
|
|
6
|
+
all: true;
|
|
7
|
+
verbatim: true;
|
|
8
|
+
}) => Promise<DnsLookupResult[]>;
|
|
1
9
|
declare function isBlockedHostname(hostname: string): boolean;
|
|
2
10
|
declare function assertSafeOutboundUrl(rawUrl: string, options?: {
|
|
3
11
|
allowHttp?: boolean;
|
|
4
12
|
}): URL;
|
|
5
|
-
|
|
13
|
+
declare function isBlockedIpAddress(address: string): boolean;
|
|
14
|
+
declare function assertSafeOutboundUrlResolved(rawUrl: string, options?: {
|
|
15
|
+
allowHttp?: boolean;
|
|
16
|
+
resolveDns?: boolean;
|
|
17
|
+
}): Promise<URL>;
|
|
18
|
+
declare function setDnsLookupForTests(lookupFn: DnsLookup): void;
|
|
19
|
+
declare function resetDnsLookupForTests(): void;
|
|
20
|
+
export { assertSafeOutboundUrl, assertSafeOutboundUrlResolved, isBlockedHostname, isBlockedIpAddress, resetDnsLookupForTests, setDnsLookupForTests, };
|
|
@@ -4,4 +4,5 @@ type TransactionHandle = {
|
|
|
4
4
|
};
|
|
5
5
|
declare function applyTenantContextToTransaction(transaction: TransactionHandle, tenantId: number): Promise<void>;
|
|
6
6
|
declare function runWithTenantDatabase<T>(tenant: TenantContext, callback: () => T | Promise<T>): Promise<T>;
|
|
7
|
-
|
|
7
|
+
declare function isInsideTenantDatabaseScope(tenantId?: number | undefined): boolean;
|
|
8
|
+
export { applyTenantContextToTransaction, isInsideTenantDatabaseScope, runWithTenantDatabase };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DatabaseConnection } from "./createConnection";
|
|
2
2
|
declare function getDatabase(): DatabaseConnection;
|
|
3
3
|
declare function pingDatabase(connection?: DatabaseConnection): Promise<boolean>;
|
|
4
4
|
declare function ensureDatabaseConnection(): Promise<DatabaseConnection>;
|
|
@@ -1,113 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// ../../src/core/errors/http.ts
|
|
3
|
-
class HttpError extends Error {
|
|
4
|
-
status;
|
|
5
|
-
details;
|
|
6
|
-
constructor(status, message, details) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = new.target.name;
|
|
9
|
-
this.status = status;
|
|
10
|
-
this.details = details;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
class BadRequestError extends HttpError {
|
|
15
|
-
constructor(message = "Bad Request", details) {
|
|
16
|
-
super(400, message, details);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
class NotFoundError extends HttpError {
|
|
21
|
-
constructor(message = "Not Found", details) {
|
|
22
|
-
super(404, message, details);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
class ConflictError extends HttpError {
|
|
27
|
-
constructor(message = "Conflict", details) {
|
|
28
|
-
super(409, message, details);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class UnprocessableEntityError extends HttpError {
|
|
33
|
-
constructor(message = "Unprocessable Entity", details) {
|
|
34
|
-
super(422, message, details);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
class ValidationError extends HttpError {
|
|
39
|
-
constructor(message = "Validation failed", details) {
|
|
40
|
-
super(422, message, details);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
class ForbiddenError extends HttpError {
|
|
45
|
-
constructor(message = "Forbidden", details) {
|
|
46
|
-
super(403, message, details);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
class UnauthorizedError extends HttpError {
|
|
51
|
-
constructor(message = "Unauthorized", details) {
|
|
52
|
-
super(401, message, details);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
class PayloadTooLargeError extends HttpError {
|
|
57
|
-
constructor(message = "Payload Too Large", details) {
|
|
58
|
-
super(413, message, details);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
class PreconditionFailedError extends HttpError {
|
|
63
|
-
constructor(message = "Precondition Failed", details) {
|
|
64
|
-
super(412, message, details);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// ../../src/core/auth/authContext.ts
|
|
69
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
70
|
-
var authContext = new AsyncLocalStorage;
|
|
71
|
-
function runWithAuthUser(user, callback) {
|
|
72
|
-
return authContext.run(user, callback);
|
|
73
|
-
}
|
|
74
|
-
function currentAuthUser() {
|
|
75
|
-
return authContext.getStore() ?? null;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ../../src/core/auth/accessControl.ts
|
|
79
|
-
var ROLE_RANK = {
|
|
80
|
-
member: 1,
|
|
81
|
-
admin: 2,
|
|
82
|
-
owner: 3
|
|
83
|
-
};
|
|
84
|
-
function isGlobalAdmin(user) {
|
|
85
|
-
return user?.role === "admin";
|
|
86
|
-
}
|
|
87
|
-
function hasMinimumOrgRole(role, minimum) {
|
|
88
|
-
if (!role) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
return ROLE_RANK[role] >= ROLE_RANK[minimum];
|
|
92
|
-
}
|
|
93
|
-
function requireAuthenticatedUser() {
|
|
94
|
-
const user = currentAuthUser();
|
|
95
|
-
if (!user) {
|
|
96
|
-
throw new ForbiddenError("Authentication required.");
|
|
97
|
-
}
|
|
98
|
-
return user;
|
|
99
|
-
}
|
|
100
|
-
function resolveUserId(user) {
|
|
101
|
-
const userId = typeof user.id === "number" ? user.id : Number(user.id);
|
|
102
|
-
if (!Number.isInteger(userId) || userId <= 0) {
|
|
103
|
-
throw new ForbiddenError("Invalid authenticated user.");
|
|
104
|
-
}
|
|
105
|
-
return userId;
|
|
106
|
-
}
|
|
107
|
-
export {
|
|
108
|
-
resolveUserId,
|
|
109
|
-
requireAuthenticatedUser,
|
|
110
|
-
isGlobalAdmin,
|
|
111
|
-
hasMinimumOrgRole,
|
|
112
|
-
ROLE_RANK
|
|
113
|
-
};
|
|
1
|
+
export * from "../../index.js";
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// ../../src/core/auth/authContext.ts
|
|
3
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
4
|
-
var authContext = new AsyncLocalStorage;
|
|
5
|
-
function runWithAuthUser(user, callback) {
|
|
6
|
-
return authContext.run(user, callback);
|
|
7
|
-
}
|
|
8
|
-
function currentAuthUser() {
|
|
9
|
-
return authContext.getStore() ?? null;
|
|
10
|
-
}
|
|
11
|
-
export {
|
|
12
|
-
runWithAuthUser,
|
|
13
|
-
currentAuthUser,
|
|
14
|
-
authContext
|
|
15
|
-
};
|
|
1
|
+
export * from "../../index.js";
|