@nestjs-kit/better-auth 0.0.0-stage → 2.1.0

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.
Files changed (142) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +1078 -2
  3. package/dist/admin.cjs +88 -0
  4. package/dist/admin.cjs.map +1 -0
  5. package/dist/admin.d.cts +14 -0
  6. package/dist/admin.d.cts.map +1 -0
  7. package/dist/admin.d.mts +14 -0
  8. package/dist/admin.d.mts.map +1 -0
  9. package/dist/admin.mjs +85 -0
  10. package/dist/admin.mjs.map +1 -0
  11. package/dist/api-key.cjs +164 -0
  12. package/dist/api-key.cjs.map +1 -0
  13. package/dist/api-key.d.cts +42 -0
  14. package/dist/api-key.d.cts.map +1 -0
  15. package/dist/api-key.d.mts +42 -0
  16. package/dist/api-key.d.mts.map +1 -0
  17. package/dist/api-key.mjs +160 -0
  18. package/dist/api-key.mjs.map +1 -0
  19. package/dist/auth-contracts-Brh_Qko9.d.cts +1654 -0
  20. package/dist/auth-contracts-Brh_Qko9.d.cts.map +1 -0
  21. package/dist/auth-contracts-Cz7C4_Ch.d.mts +1654 -0
  22. package/dist/auth-contracts-Cz7C4_Ch.d.mts.map +1 -0
  23. package/dist/auth-decorators-B1mFnGJ6.mjs +284 -0
  24. package/dist/auth-decorators-B1mFnGJ6.mjs.map +1 -0
  25. package/dist/auth-decorators-Cu_nxWnF.cjs +421 -0
  26. package/dist/auth-decorators-Cu_nxWnF.cjs.map +1 -0
  27. package/dist/auth-errors-C3rbTV9p.mjs +301 -0
  28. package/dist/auth-errors-C3rbTV9p.mjs.map +1 -0
  29. package/dist/auth-errors-DmiKl0L_.cjs +378 -0
  30. package/dist/auth-errors-DmiKl0L_.cjs.map +1 -0
  31. package/dist/auth-guard-CLyhAEEj.cjs +136 -0
  32. package/dist/auth-guard-CLyhAEEj.cjs.map +1 -0
  33. package/dist/auth-guard-h9QB_l11.mjs +125 -0
  34. package/dist/auth-guard-h9QB_l11.mjs.map +1 -0
  35. package/dist/auth-module-BgcY2HpA.cjs +2809 -0
  36. package/dist/auth-module-BgcY2HpA.cjs.map +1 -0
  37. package/dist/auth-module-CtHx3gRU.mjs +2708 -0
  38. package/dist/auth-module-CtHx3gRU.mjs.map +1 -0
  39. package/dist/auth-scope-interceptor-BjxAL1-S.cjs +290 -0
  40. package/dist/auth-scope-interceptor-BjxAL1-S.cjs.map +1 -0
  41. package/dist/auth-scope-interceptor-DYPn3b8M.mjs +231 -0
  42. package/dist/auth-scope-interceptor-DYPn3b8M.mjs.map +1 -0
  43. package/dist/bridge-protocol-BDw8opAG.cjs +25 -0
  44. package/dist/bridge-protocol-BDw8opAG.cjs.map +1 -0
  45. package/dist/bridge-protocol-c66aEkr5.mjs +8 -0
  46. package/dist/bridge-protocol-c66aEkr5.mjs.map +1 -0
  47. package/dist/decorate-Cr4Q7bNE.cjs +319 -0
  48. package/dist/decorate-Cr4Q7bNE.cjs.map +1 -0
  49. package/dist/decorate-Dt0e9K6R.mjs +80 -0
  50. package/dist/decorate-Dt0e9K6R.mjs.map +1 -0
  51. package/dist/express.cjs +256 -0
  52. package/dist/express.cjs.map +1 -0
  53. package/dist/express.d.cts +37 -0
  54. package/dist/express.d.cts.map +1 -0
  55. package/dist/express.d.mts +37 -0
  56. package/dist/express.d.mts.map +1 -0
  57. package/dist/express.mjs +254 -0
  58. package/dist/express.mjs.map +1 -0
  59. package/dist/fastify.cjs +218 -0
  60. package/dist/fastify.cjs.map +1 -0
  61. package/dist/fastify.d.cts +28 -0
  62. package/dist/fastify.d.cts.map +1 -0
  63. package/dist/fastify.d.mts +28 -0
  64. package/dist/fastify.d.mts.map +1 -0
  65. package/dist/fastify.mjs +216 -0
  66. package/dist/fastify.mjs.map +1 -0
  67. package/dist/graphql.cjs +509 -0
  68. package/dist/graphql.cjs.map +1 -0
  69. package/dist/graphql.d.cts +38 -0
  70. package/dist/graphql.d.cts.map +1 -0
  71. package/dist/graphql.d.mts +38 -0
  72. package/dist/graphql.d.mts.map +1 -0
  73. package/dist/graphql.mjs +503 -0
  74. package/dist/graphql.mjs.map +1 -0
  75. package/dist/index.cjs +86 -0
  76. package/dist/index.d.cts +2 -0
  77. package/dist/index.d.mts +2 -0
  78. package/dist/index.mjs +8 -0
  79. package/dist/microservices.cjs +231 -0
  80. package/dist/microservices.cjs.map +1 -0
  81. package/dist/microservices.d.cts +39 -0
  82. package/dist/microservices.d.cts.map +1 -0
  83. package/dist/microservices.d.mts +39 -0
  84. package/dist/microservices.d.mts.map +1 -0
  85. package/dist/microservices.mjs +222 -0
  86. package/dist/microservices.mjs.map +1 -0
  87. package/dist/organization.cjs +191 -0
  88. package/dist/organization.cjs.map +1 -0
  89. package/dist/organization.d.cts +40 -0
  90. package/dist/organization.d.cts.map +1 -0
  91. package/dist/organization.d.mts +40 -0
  92. package/dist/organization.d.mts.map +1 -0
  93. package/dist/organization.mjs +177 -0
  94. package/dist/organization.mjs.map +1 -0
  95. package/dist/platform-CZl7TY8j.mjs +414 -0
  96. package/dist/platform-CZl7TY8j.mjs.map +1 -0
  97. package/dist/platform-YICqqYv6.cjs +473 -0
  98. package/dist/platform-YICqqYv6.cjs.map +1 -0
  99. package/dist/platform.cjs +10 -0
  100. package/dist/platform.d.cts +43 -0
  101. package/dist/platform.d.cts.map +1 -0
  102. package/dist/platform.d.mts +43 -0
  103. package/dist/platform.d.mts.map +1 -0
  104. package/dist/platform.mjs +1 -0
  105. package/dist/plugin.cjs +323 -0
  106. package/dist/plugin.cjs.map +1 -0
  107. package/dist/plugin.d.cts +24 -0
  108. package/dist/plugin.d.cts.map +1 -0
  109. package/dist/plugin.d.mts +24 -0
  110. package/dist/plugin.d.mts.map +1 -0
  111. package/dist/plugin.mjs +321 -0
  112. package/dist/plugin.mjs.map +1 -0
  113. package/dist/principal-readings-Chmt6rQV.cjs +208 -0
  114. package/dist/principal-readings-Chmt6rQV.cjs.map +1 -0
  115. package/dist/principal-readings-Ied2staw.mjs +191 -0
  116. package/dist/principal-readings-Ied2staw.mjs.map +1 -0
  117. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  118. package/dist/testing/conformance.cjs +6214 -0
  119. package/dist/testing/conformance.cjs.map +1 -0
  120. package/dist/testing/conformance.d.cts +528 -0
  121. package/dist/testing/conformance.d.cts.map +1 -0
  122. package/dist/testing/conformance.d.mts +528 -0
  123. package/dist/testing/conformance.d.mts.map +1 -0
  124. package/dist/testing/conformance.mjs +6204 -0
  125. package/dist/testing/conformance.mjs.map +1 -0
  126. package/dist/testing.cjs +221 -0
  127. package/dist/testing.cjs.map +1 -0
  128. package/dist/testing.d.cts +64 -0
  129. package/dist/testing.d.cts.map +1 -0
  130. package/dist/testing.d.mts +64 -0
  131. package/dist/testing.d.mts.map +1 -0
  132. package/dist/testing.mjs +214 -0
  133. package/dist/testing.mjs.map +1 -0
  134. package/dist/websockets.cjs +396 -0
  135. package/dist/websockets.cjs.map +1 -0
  136. package/dist/websockets.d.cts +67 -0
  137. package/dist/websockets.d.cts.map +1 -0
  138. package/dist/websockets.d.mts +67 -0
  139. package/dist/websockets.d.mts.map +1 -0
  140. package/dist/websockets.mjs +383 -0
  141. package/dist/websockets.mjs.map +1 -0
  142. package/package.json +327 -3
@@ -0,0 +1,222 @@
1
+ import { n as BetterAuthConfigurationError, t as AuthFailures } from "./auth-errors-C3rbTV9p.mjs";
2
+ import { Logger } from "@nestjs/common";
3
+ import { MetadataScanner } from "@nestjs/core";
4
+ import * as microservices from "@nestjs/microservices";
5
+ import { MessagePattern, RpcException } from "@nestjs/microservices";
6
+ //#region src/rpc-carriers.ts
7
+ const credentialNames = [
8
+ "authorization",
9
+ "cookie",
10
+ "x-api-key"
11
+ ];
12
+ function record(value) {
13
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
14
+ }
15
+ function method(value, name) {
16
+ const candidate = record(value)?.[name];
17
+ return typeof candidate === "function" ? candidate.bind(value) : void 0;
18
+ }
19
+ function contextOf(context) {
20
+ return context.switchToRpc().getContext();
21
+ }
22
+ function extract(input, allow) {
23
+ const headers = new Headers();
24
+ const allowed = new Set(allow.map((name) => name.toLowerCase()));
25
+ for (const name of [
26
+ "host",
27
+ "x-forwarded-host",
28
+ "x-forwarded-proto",
29
+ "set-cookie"
30
+ ]) allowed.delete(name);
31
+ const source = record(input);
32
+ if (!source) return headers;
33
+ for (const name of Object.keys(source)) {
34
+ const normalized = name.toLowerCase();
35
+ if (!allowed.has(normalized)) continue;
36
+ const value = source[name];
37
+ const values = Array.isArray(value) ? value : [value];
38
+ if (values.length === 0) throw AuthFailures.rejected({
39
+ status: 401,
40
+ reason: "MALFORMED_CREDENTIALS"
41
+ });
42
+ for (const item of values) {
43
+ const text = typeof item === "string" ? item : Buffer.isBuffer(item) ? item.toString("utf8") : void 0;
44
+ if (text === void 0 || /[\r\n\0]/.test(text)) throw AuthFailures.rejected({
45
+ status: 401,
46
+ reason: "MALFORMED_CREDENTIALS"
47
+ });
48
+ try {
49
+ headers.append(normalized, text);
50
+ } catch {
51
+ throw AuthFailures.rejected({
52
+ status: 401,
53
+ reason: "MALFORMED_CREDENTIALS"
54
+ });
55
+ }
56
+ }
57
+ }
58
+ return headers;
59
+ }
60
+ function grpcCarrier(options = {}) {
61
+ return {
62
+ id: "grpc",
63
+ matches: (context) => !!method(context.getArgByIndex(1), "get") && !!method(context.getArgByIndex(1), "getMap"),
64
+ headers: (context) => extract(method(context.getArgByIndex(1), "getMap")?.(), options.metadata ?? credentialNames),
65
+ toException(failure) {
66
+ const name = failure.status === 401 ? "GrpcUnauthenticatedException" : failure.status === 403 ? "GrpcPermissionDeniedException" : "GrpcResourceExhaustedException";
67
+ const Native = microservices[name];
68
+ return new microservices.RpcException(Native ? new Native(failure.message).getError() : {
69
+ code: failure.status === 401 ? 16 : failure.status === 403 ? 7 : 8,
70
+ message: failure.message
71
+ });
72
+ }
73
+ };
74
+ }
75
+ function natsCarrier(options = {}) {
76
+ return {
77
+ id: "nats",
78
+ matches: (context) => !!method(contextOf(context), "getHeaders"),
79
+ headers(context) {
80
+ const input = method(contextOf(context), "getHeaders")?.();
81
+ const keys = method(input, "keys")?.();
82
+ const get = method(input, "get");
83
+ const values = Object.create(null);
84
+ if (Array.isArray(keys) && get) {
85
+ for (const key of keys) if (typeof key === "string") values[key] = get(key);
86
+ }
87
+ return extract(values, options.headers ?? credentialNames);
88
+ }
89
+ };
90
+ }
91
+ function kafkaCarrier(options = {}) {
92
+ const message = (context) => record(method(contextOf(context), "getMessage")?.());
93
+ return {
94
+ id: "kafka",
95
+ matches: (context) => message(context) !== void 0 && "headers" in message(context),
96
+ headers: (context) => extract(message(context)?.headers, options.headers ?? credentialNames)
97
+ };
98
+ }
99
+ function rmqCarrier(options = {}) {
100
+ const message = (context) => record(method(contextOf(context), "getMessage")?.());
101
+ return {
102
+ id: "rmq",
103
+ matches: (context) => message(context) !== void 0 && "properties" in message(context),
104
+ headers: (context) => extract(record(message(context)?.properties)?.headers, options.headers ?? credentialNames)
105
+ };
106
+ }
107
+ function mqttCarrier(options = {}) {
108
+ return {
109
+ id: "mqtt",
110
+ matches: (context) => !!method(contextOf(context), "getPacket"),
111
+ headers: (context) => extract(record(record(method(contextOf(context), "getPacket")?.())?.properties)?.userProperties, options.userProperties ?? credentialNames)
112
+ };
113
+ }
114
+ function payloadCarrier(options = {}) {
115
+ const payload = (context) => {
116
+ const data = record(context.switchToRpc().getData());
117
+ const field = options.field ?? "auth";
118
+ return data && Object.hasOwn(data, field) ? record(data[field]) : void 0;
119
+ };
120
+ return {
121
+ id: "payload",
122
+ matches: (context) => payload(context) !== void 0,
123
+ headers: (context) => extract(payload(context), credentialNames)
124
+ };
125
+ }
126
+ const defaultCarriers = Object.freeze([
127
+ grpcCarrier(),
128
+ natsCarrier(),
129
+ kafkaCarrier(),
130
+ rmqCarrier(),
131
+ mqttCarrier(),
132
+ payloadCarrier()
133
+ ]);
134
+ //#endregion
135
+ //#region src/rpc-transport.ts
136
+ function rpcTransport(options = {}) {
137
+ const carriers = [...options.carriers ?? defaultCarriers];
138
+ const select = (context) => carriers.find((carrier) => carrier.matches(context));
139
+ const grpc = grpcCarrier();
140
+ return {
141
+ id: "rpc",
142
+ requires: { hostlessCalls: true },
143
+ handles: (context) => context.getType() === "rpc",
144
+ describe(context) {
145
+ const candidate = context.switchToRpc().getContext();
146
+ const key = candidate !== null && typeof candidate === "object" ? candidate : context.getArgs();
147
+ return {
148
+ key,
149
+ invocation: key,
150
+ cookies: null,
151
+ clientIp: null,
152
+ headers() {
153
+ const input = select(context)?.headers(context);
154
+ try {
155
+ return new Headers(input);
156
+ } catch {
157
+ throw AuthFailures.rejected({
158
+ status: 401,
159
+ reason: "MALFORMED_CREDENTIALS"
160
+ });
161
+ }
162
+ },
163
+ param(name) {
164
+ const data = context.switchToRpc().getData();
165
+ return data !== null && typeof data === "object" && Object.hasOwn(data, name) ? data[name] : void 0;
166
+ }
167
+ };
168
+ },
169
+ toException(failure, context) {
170
+ const carrier = select(context);
171
+ return carrier?.toException ? carrier.toException(failure, context) : new RpcException({
172
+ status: "error",
173
+ statusCode: failure.status,
174
+ code: failure.code,
175
+ ...failure.reason ? { reason: failure.reason } : {},
176
+ message: failure.message
177
+ });
178
+ },
179
+ toInternalException(error, context, info) {
180
+ if (!grpc.matches(context)) return error;
181
+ if (!info.repeated) new Logger("BetterAuthRpc").error(error);
182
+ return new RpcException({
183
+ code: 13,
184
+ message: "Internal server error"
185
+ });
186
+ },
187
+ validate(context) {
188
+ class Probe {
189
+ handler() {}
190
+ }
191
+ MessagePattern("nestjs-kit-better-auth-probe")(Probe.prototype, "handler", Object.getOwnPropertyDescriptor(Probe.prototype, "handler"));
192
+ const patterns = Reflect.getMetadata("microservices:pattern", Probe.prototype.handler);
193
+ if (!Array.isArray(patterns) || patterns[0] !== "nestjs-kit-better-auth-probe") throw new BetterAuthConfigurationError("NEST_METADATA_KEY_CHANGED", "Nest RPC pattern metadata failed its canary");
194
+ const explicit = context.hasHttpAdapter && !options.inheritAppConfig;
195
+ const scanner = new MetadataScanner();
196
+ for (const wrapper of context.discovery.getControllers()) {
197
+ const target = wrapper.metatype;
198
+ if (!target?.prototype || wrapper.isAlias) continue;
199
+ for (const name of scanner.getAllMethodNames(target.prototype)) {
200
+ if (Reflect.getMetadata("microservices:pattern", target.prototype[name]) === void 0) continue;
201
+ context.claim(target, name, explicit ? "explicit" : "global", {
202
+ code: "RPC_HANDLER_UNGUARDED",
203
+ everyHandler: explicit,
204
+ coverage: explicit ? options.hybridCoverage ?? "error" : "error",
205
+ hint: "Add @UseBetterAuth() or @Public() to the RPC controller/handler, or assert inheritAppConfig and pass { inheritAppConfig: true } to every connectMicroservice call."
206
+ });
207
+ }
208
+ }
209
+ },
210
+ advise() {
211
+ return options.inheritAppConfig ? [{
212
+ level: "warn",
213
+ code: "W_RPC_INHERIT_APP_CONFIG_ASSERTED",
214
+ message: "RPC coverage assumes every connectMicroservice() call passes { inheritAppConfig: true }. Prefer @UseBetterAuth() on message controllers for verifiable coverage."
215
+ }] : [];
216
+ }
217
+ };
218
+ }
219
+ //#endregion
220
+ export { defaultCarriers, grpcCarrier, kafkaCarrier, mqttCarrier, natsCarrier, payloadCarrier, rmqCarrier, rpcTransport };
221
+
222
+ //# sourceMappingURL=microservices.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microservices.mjs","names":[],"sources":["../src/rpc-carriers.ts","../src/rpc-transport.ts"],"sourcesContent":["import type { ExecutionContext } from \"@nestjs/common\";\nimport * as microservices from \"@nestjs/microservices\";\nimport { AuthFailures, type AuthFailure } from \"./auth-errors.js\";\n\nexport interface RpcCredentialCarrier {\n readonly id: string;\n matches(context: ExecutionContext): boolean;\n headers(context: ExecutionContext): HeadersInit | undefined;\n toException?(failure: AuthFailure, context: ExecutionContext): unknown;\n}\n\nconst credentialNames = [\"authorization\", \"cookie\", \"x-api-key\"] as const;\n\ntype RecordValue = Record<string, unknown>;\nfunction record(value: unknown): RecordValue | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as RecordValue)\n : undefined;\n}\nfunction method(\n value: unknown,\n name: string,\n): ((...args: unknown[]) => unknown) | undefined {\n const target = record(value);\n const candidate = target?.[name];\n return typeof candidate === \"function\" ? candidate.bind(value) : undefined;\n}\nfunction contextOf(context: ExecutionContext): unknown {\n return context.switchToRpc().getContext<unknown>();\n}\nfunction extract(input: unknown, allow: readonly string[]): Headers {\n const headers = new Headers();\n const allowed = new Set(allow.map((name) => name.toLowerCase()));\n // Host and forwarding metadata must never influence hostless authentication.\n for (const name of [\n \"host\",\n \"x-forwarded-host\",\n \"x-forwarded-proto\",\n \"set-cookie\",\n ]) {\n allowed.delete(name);\n }\n const source = record(input);\n if (!source) {\n return headers;\n }\n for (const name of Object.keys(source)) {\n const normalized = name.toLowerCase();\n if (!allowed.has(normalized)) {\n continue;\n }\n const value = source[name];\n const values = Array.isArray(value) ? value : [value];\n if (values.length === 0) {\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n for (const item of values) {\n const text =\n typeof item === \"string\"\n ? item\n : Buffer.isBuffer(item)\n ? item.toString(\"utf8\")\n : undefined;\n if (text === undefined || /[\\r\\n\\0]/.test(text)) {\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n try {\n headers.append(normalized, text);\n } catch {\n // Web Headers errors can embed credentials in their message. Never retain\n // that error, and never discard one bad credential to try another one.\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n }\n }\n return headers;\n}\n\nexport function grpcCarrier(\n options: { metadata?: readonly string[] } = {},\n): RpcCredentialCarrier {\n return {\n id: \"grpc\",\n matches: (context) =>\n !!method(context.getArgByIndex(1), \"get\") &&\n !!method(context.getArgByIndex(1), \"getMap\"),\n headers: (context) =>\n extract(\n method(context.getArgByIndex(1), \"getMap\")?.(),\n options.metadata ?? credentialNames,\n ),\n toException(failure) {\n const name =\n failure.status === 401\n ? \"GrpcUnauthenticatedException\"\n : failure.status === 403\n ? \"GrpcPermissionDeniedException\"\n : \"GrpcResourceExhaustedException\";\n const Native = (\n microservices as unknown as Record<\n string,\n new (\n message: string,\n ) => Error & { getError(): object }\n >\n )[name];\n // Native gRPC exceptions require an opt-in Nest filter. Wrap their payload\n // so the default RPC filter also delivers the numeric status.\n return new microservices.RpcException(\n Native\n ? new Native(failure.message).getError()\n : {\n code:\n failure.status === 401 ? 16 : failure.status === 403 ? 7 : 8,\n message: failure.message,\n },\n );\n },\n };\n}\n\nexport function natsCarrier(\n options: { headers?: readonly string[] } = {},\n): RpcCredentialCarrier {\n return {\n id: \"nats\",\n matches: (context) => !!method(contextOf(context), \"getHeaders\"),\n headers(context) {\n const input = method(contextOf(context), \"getHeaders\")?.();\n const keys = method(input, \"keys\")?.();\n const get = method(input, \"get\");\n const values: RecordValue = Object.create(null);\n if (Array.isArray(keys) && get) {\n for (const key of keys) {\n if (typeof key === \"string\") {\n values[key] = get(key);\n }\n }\n }\n return extract(values, options.headers ?? credentialNames);\n },\n };\n}\n\nexport function kafkaCarrier(\n options: { headers?: readonly string[] } = {},\n): RpcCredentialCarrier {\n const message = (context: ExecutionContext) =>\n record(method(contextOf(context), \"getMessage\")?.());\n return {\n id: \"kafka\",\n matches: (context) =>\n message(context) !== undefined && \"headers\" in message(context)!,\n headers: (context) =>\n extract(message(context)?.headers, options.headers ?? credentialNames),\n };\n}\n\nexport function rmqCarrier(\n options: { headers?: readonly string[] } = {},\n): RpcCredentialCarrier {\n const message = (context: ExecutionContext) =>\n record(method(contextOf(context), \"getMessage\")?.());\n return {\n id: \"rmq\",\n matches: (context) =>\n message(context) !== undefined && \"properties\" in message(context)!,\n headers: (context) =>\n extract(\n record(message(context)?.properties)?.headers,\n options.headers ?? credentialNames,\n ),\n };\n}\n\nexport function mqttCarrier(\n options: { userProperties?: readonly string[] } = {},\n): RpcCredentialCarrier {\n return {\n id: \"mqtt\",\n matches: (context) => !!method(contextOf(context), \"getPacket\"),\n headers: (context) =>\n extract(\n record(record(method(contextOf(context), \"getPacket\")?.())?.properties)\n ?.userProperties,\n options.userProperties ?? credentialNames,\n ),\n };\n}\n\nexport function payloadCarrier(\n options: { field?: string } = {},\n): RpcCredentialCarrier {\n const payload = (context: ExecutionContext) => {\n const data = record(context.switchToRpc().getData<unknown>());\n const field = options.field ?? \"auth\";\n return data && Object.hasOwn(data, field) ? record(data[field]) : undefined;\n };\n return {\n id: \"payload\",\n matches: (context) => payload(context) !== undefined,\n headers: (context) => extract(payload(context), credentialNames),\n };\n}\n\nexport const defaultCarriers: readonly RpcCredentialCarrier[] = Object.freeze([\n grpcCarrier(),\n natsCarrier(),\n kafkaCarrier(),\n rmqCarrier(),\n mqttCarrier(),\n payloadCarrier(),\n]);\n","import { Logger, type ExecutionContext } from \"@nestjs/common\";\nimport { MetadataScanner } from \"@nestjs/core\";\nimport { MessagePattern, RpcException } from \"@nestjs/microservices\";\nimport type {\n AuthTransport,\n BootAdvice,\n ExtensionRef,\n TransportCall,\n TransportValidationContext,\n} from \"./auth-contracts.js\";\nimport {\n BetterAuthConfigurationError,\n AuthFailures,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport {\n defaultCarriers,\n grpcCarrier,\n type RpcCredentialCarrier,\n} from \"./rpc-carriers.js\";\n\nexport interface RpcTransportOptions {\n carriers?: readonly RpcCredentialCarrier[];\n hybridCoverage?: \"error\" | \"warn\" | \"off\";\n inheritAppConfig?: boolean;\n}\n\nexport function rpcTransport(\n options: RpcTransportOptions = {},\n): ExtensionRef<AuthTransport> {\n const carriers = [...(options.carriers ?? defaultCarriers)];\n const select = (context: ExecutionContext) =>\n carriers.find((carrier) => carrier.matches(context));\n const grpc = grpcCarrier();\n return {\n id: \"rpc\",\n requires: { hostlessCalls: true },\n handles: (context) => context.getType() === \"rpc\",\n describe(context): TransportCall {\n const candidate = context.switchToRpc().getContext<unknown>();\n const key =\n candidate !== null && typeof candidate === \"object\"\n ? candidate\n : context.getArgs();\n return {\n key,\n invocation: key,\n cookies: null,\n clientIp: null,\n headers() {\n const input = select(context)?.headers(context);\n try {\n return new Headers(input);\n } catch {\n // Custom carriers may return a raw HeadersInit. Conversion errors\n // include its values, so discard the original error and its cause.\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n },\n param(name) {\n const data = context.switchToRpc().getData<unknown>();\n return data !== null &&\n typeof data === \"object\" &&\n Object.hasOwn(data, name)\n ? (data as Record<string, unknown>)[name]\n : undefined;\n },\n };\n },\n toException(failure: AuthFailure, context) {\n const carrier = select(context);\n return carrier?.toException\n ? carrier.toException(failure, context)\n : new RpcException({\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n });\n },\n toInternalException(error, context, info) {\n if (!grpc.matches(context)) {\n return error;\n }\n if (!info.repeated) {\n new Logger(\"BetterAuthRpc\").error(error);\n }\n return new RpcException({ code: 13, message: \"Internal server error\" });\n },\n validate(context: TransportValidationContext) {\n class Probe {\n handler(): void {}\n }\n MessagePattern(\"nestjs-kit-better-auth-probe\")(\n Probe.prototype,\n \"handler\",\n Object.getOwnPropertyDescriptor(Probe.prototype, \"handler\")!,\n );\n const patterns: unknown = Reflect.getMetadata(\n \"microservices:pattern\",\n Probe.prototype.handler,\n );\n if (\n !Array.isArray(patterns) ||\n patterns[0] !== \"nestjs-kit-better-auth-probe\"\n ) {\n throw new BetterAuthConfigurationError(\n \"NEST_METADATA_KEY_CHANGED\",\n \"Nest RPC pattern metadata failed its canary\",\n );\n }\n const explicit = context.hasHttpAdapter && !options.inheritAppConfig;\n const scanner = new MetadataScanner();\n for (const wrapper of context.discovery.getControllers()) {\n const target = wrapper.metatype;\n if (!target?.prototype || wrapper.isAlias) {\n continue;\n }\n for (const name of scanner.getAllMethodNames(target.prototype)) {\n if (\n Reflect.getMetadata(\n \"microservices:pattern\",\n target.prototype[name],\n ) === undefined\n ) {\n continue;\n }\n context.claim(target, name, explicit ? \"explicit\" : \"global\", {\n code: \"RPC_HANDLER_UNGUARDED\",\n everyHandler: explicit,\n coverage: explicit ? (options.hybridCoverage ?? \"error\") : \"error\",\n hint: \"Add @UseBetterAuth() or @Public() to the RPC controller/handler, or assert inheritAppConfig and pass { inheritAppConfig: true } to every connectMicroservice call.\",\n });\n }\n }\n },\n advise(): readonly BootAdvice[] {\n return options.inheritAppConfig\n ? [\n {\n level: \"warn\",\n code: \"W_RPC_INHERIT_APP_CONFIG_ASSERTED\",\n message:\n \"RPC coverage assumes every connectMicroservice() call passes { inheritAppConfig: true }. Prefer @UseBetterAuth() on message controllers for verifiable coverage.\",\n },\n ]\n : [];\n },\n } satisfies AuthTransport;\n}\n"],"mappings":"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"}
@@ -0,0 +1,191 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_auth_errors = require("./auth-errors-DmiKl0L_.cjs");
3
+ const require_auth_decorators = require("./auth-decorators-Cu_nxWnF.cjs");
4
+ let better_auth_api = require("better-auth/api");
5
+ //#region src/organization.ts
6
+ const ACTIVE_ORGANIZATION_ID = Symbol.for("@nestjs-kit/better-auth:org:active-organization-id");
7
+ const ACTIVE_MEMBER_ROLE = Symbol.for("@nestjs-kit/better-auth:org:active-member-role");
8
+ const ActiveOrganizationId = require_auth_decorators.defineInvocationParam(ACTIVE_ORGANIZATION_ID, { missing: "ORGANIZATION_REQUIRED" });
9
+ const ActiveMemberRole = require_auth_decorators.defineInvocationParam(ACTIVE_MEMBER_ROLE, { missing: "MEMBER_ROLE_REQUIRED" });
10
+ const REF = Symbol.for("@nestjs-kit/better-auth:org:ref");
11
+ function organizationRef(resolve, options = {}) {
12
+ return Object.assign((ctx) => resolve(ctx), options);
13
+ }
14
+ function activeOrganization() {
15
+ return Object.assign(organizationRef(async (ctx) => {
16
+ const value = ctx.principal.session.session?.activeOrganizationId;
17
+ if (value !== void 0) return value;
18
+ if (!await ctx.auth.hasPlugin("custom-session")) return;
19
+ try {
20
+ return (await ctx.memo(JSON.stringify(["org:activeMember"]), () => ctx.auth.run({
21
+ cookies: ctx.cookies,
22
+ inbound: () => ctx.headers,
23
+ internal: true
24
+ }, () => ctx.auth.api.getActiveMember({ headers: ctx.headers }))))?.organizationId;
25
+ } catch (error) {
26
+ if ((0, better_auth_api.isAPIError)(error) && error.statusCode === 400 && (error.body?.code === "NO_ACTIVE_ORGANIZATION" || error.body?.code === "MEMBER_NOT_FOUND")) return;
27
+ throw error;
28
+ }
29
+ }, { missingReason: "NO_ACTIVE_ORGANIZATION" }), { [REF]: { kind: "active" } });
30
+ }
31
+ function fromParam(name) {
32
+ return Object.assign(organizationRef((ctx) => ctx.param(name)), { [REF]: {
33
+ kind: "param",
34
+ name
35
+ } });
36
+ }
37
+ function fromHeader(name) {
38
+ return organizationRef((ctx) => ctx.headers.get(name));
39
+ }
40
+ function requirements(expressions) {
41
+ return expressions.flatMap((expression) => "anyOf" in expression ? requirements(expression.anyOf) : "allOf" in expression ? requirements(expression.allOf) : [expression]);
42
+ }
43
+ function advise(ctx, policy) {
44
+ const advice = [];
45
+ for (const handler of ctx.handlers) for (const requirement of requirements(handler.plan.requirements)) {
46
+ if (requirement.policy !== policy) continue;
47
+ const marker = requirement.params.organization[REF];
48
+ if (marker?.kind === "active") {
49
+ const input = handler.inputs.find((name) => [
50
+ "orgId",
51
+ "organizationId",
52
+ "organization",
53
+ "orgSlug"
54
+ ].includes(name));
55
+ if (input) advice.push({
56
+ level: "warn",
57
+ code: "W_ORG_PARAM_IGNORED",
58
+ message: `${handler.plan.site} checks the active organization but accepts ${input}.`,
59
+ hint: input === "orgSlug" ? "Map the slug to an ID with organizationRef and auth.api.listOrganizations({ headers })." : `Use fromParam('${input}').`
60
+ });
61
+ } else if (marker?.kind === "param" && !handler.inputs.includes(marker.name)) advice.push({
62
+ level: "warn",
63
+ code: "W_ORG_PARAM_MISSING",
64
+ message: `${handler.plan.site} reads ${marker.name}, absent from claimed inputs: ${handler.inputs.join(", ") || "none"}.`,
65
+ hint: "Use the correct input name, a method-level organizationRef, or SkipDefaultRequirements with a method-level requirement."
66
+ });
67
+ }
68
+ return advice;
69
+ }
70
+ const requires = {
71
+ plugins: ["organization"],
72
+ principals: ["session"],
73
+ presentsCredentials: true
74
+ };
75
+ const orgPermissionPolicy = {
76
+ id: "better-auth:organization/permission",
77
+ requires,
78
+ advise: (ctx) => advise(ctx, orgPermissionPolicy),
79
+ validate({ permissions }) {
80
+ if (!Object.keys(permissions).length || Object.values(permissions).some((actions) => !Array.isArray(actions) || !actions.length)) throw new require_auth_errors.BetterAuthConfigurationError("EMPTY_PERMISSIONS", "Organization permissions must contain a resource and actions.");
81
+ },
82
+ async evaluate({ permissions, organization }, context) {
83
+ const organizationId = await organization(context);
84
+ if (typeof organizationId !== "string" || !organizationId.trim()) return {
85
+ effect: "deny",
86
+ reason: organization.missingReason ?? "ORGANIZATION_REQUIRED"
87
+ };
88
+ const stable = Object.entries(permissions).sort(([a], [b]) => a.localeCompare(b)).map(([resource, actions]) => [resource, [...actions].sort()]);
89
+ try {
90
+ if (!(await context.memo(JSON.stringify([
91
+ "org:hasPermission",
92
+ organizationId,
93
+ stable
94
+ ]), () => context.auth.run({
95
+ cookies: context.cookies,
96
+ inbound: () => context.headers,
97
+ internal: true
98
+ }, () => context.auth.api.hasPermission({
99
+ headers: context.headers,
100
+ body: {
101
+ organizationId,
102
+ permissions
103
+ }
104
+ })))).success) return {
105
+ effect: "deny",
106
+ reason: "MISSING_PERMISSION"
107
+ };
108
+ context.provide(ACTIVE_ORGANIZATION_ID, organizationId);
109
+ return { effect: "allow" };
110
+ } catch (error) {
111
+ if ((0, better_auth_api.isAPIError)(error) && error.body?.code === "USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION") return {
112
+ effect: "deny",
113
+ reason: "USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION"
114
+ };
115
+ throw error;
116
+ }
117
+ }
118
+ };
119
+ const orgMemberPolicy = {
120
+ id: "better-auth:organization/member",
121
+ requires,
122
+ advise: (ctx) => advise(ctx, orgMemberPolicy),
123
+ async evaluate({ organization }, context) {
124
+ const organizationId = await organization(context);
125
+ if (typeof organizationId !== "string" || !organizationId.trim()) return {
126
+ effect: "deny",
127
+ reason: organization.missingReason ?? "ORGANIZATION_REQUIRED"
128
+ };
129
+ try {
130
+ const result = await context.memo(JSON.stringify(["org:activeMemberRole", organizationId]), () => context.auth.run({
131
+ cookies: context.cookies,
132
+ inbound: () => context.headers,
133
+ internal: true
134
+ }, () => context.auth.api.getActiveMemberRole({
135
+ headers: context.headers,
136
+ query: { organizationId }
137
+ })));
138
+ if (typeof result.role !== "string" || !result.role.trim()) return {
139
+ effect: "deny",
140
+ reason: "YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION"
141
+ };
142
+ context.provide(ACTIVE_ORGANIZATION_ID, organizationId);
143
+ context.provide(ACTIVE_MEMBER_ROLE, result.role);
144
+ return { effect: "allow" };
145
+ } catch (error) {
146
+ if ((0, better_auth_api.isAPIError)(error) && error.body?.code === "YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION") return {
147
+ effect: "deny",
148
+ reason: "YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION"
149
+ };
150
+ throw error;
151
+ }
152
+ }
153
+ };
154
+ function orgPermission(permissions, options = {}) {
155
+ return {
156
+ policy: orgPermissionPolicy,
157
+ params: {
158
+ permissions,
159
+ organization: options.organization ?? activeOrganization()
160
+ }
161
+ };
162
+ }
163
+ function RequireOrgPermission(permissions, options) {
164
+ return require_auth_decorators.Require(orgPermission(permissions, options));
165
+ }
166
+ function orgMember(options = {}) {
167
+ return {
168
+ policy: orgMemberPolicy,
169
+ params: { organization: options.organization ?? activeOrganization() }
170
+ };
171
+ }
172
+ function RequireOrgMember(options) {
173
+ return require_auth_decorators.Require(orgMember(options));
174
+ }
175
+ //#endregion
176
+ exports.ACTIVE_MEMBER_ROLE = ACTIVE_MEMBER_ROLE;
177
+ exports.ACTIVE_ORGANIZATION_ID = ACTIVE_ORGANIZATION_ID;
178
+ exports.ActiveMemberRole = ActiveMemberRole;
179
+ exports.ActiveOrganizationId = ActiveOrganizationId;
180
+ exports.RequireOrgMember = RequireOrgMember;
181
+ exports.RequireOrgPermission = RequireOrgPermission;
182
+ exports.activeOrganization = activeOrganization;
183
+ exports.fromHeader = fromHeader;
184
+ exports.fromParam = fromParam;
185
+ exports.orgMember = orgMember;
186
+ exports.orgMemberPolicy = orgMemberPolicy;
187
+ exports.orgPermission = orgPermission;
188
+ exports.orgPermissionPolicy = orgPermissionPolicy;
189
+ exports.organizationRef = organizationRef;
190
+
191
+ //# sourceMappingURL=organization.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organization.cjs","names":["defineInvocationParam","isAPIError","BetterAuthConfigurationError","Require"],"sources":["../src/organization.ts"],"sourcesContent":["import { isAPIError } from \"better-auth/api\";\nimport type {\n AuthorizationContext,\n AuthorizationPolicy,\n BootAdvice,\n BootAdviceContext,\n Requirement,\n RequirementExpr,\n} from \"./auth-contracts.js\";\nimport { defineInvocationParam, Require } from \"./auth-decorators.js\";\nimport { BetterAuthConfigurationError } from \"./auth-errors.js\";\nimport type { OrgPermissions, SessionPrincipal } from \"./auth-types.js\";\nexport type { OrgPermissions } from \"./auth-types.js\";\nexport interface OrganizationRef {\n (ctx: AuthorizationContext): unknown | Promise<unknown>;\n readonly missingReason?: string;\n}\nexport interface OrgPermissionParams {\n readonly permissions: OrgPermissions;\n readonly organization: OrganizationRef;\n}\nexport interface OrgMemberParams {\n readonly organization: OrganizationRef;\n}\nexport const ACTIVE_ORGANIZATION_ID = Symbol.for(\n \"@nestjs-kit/better-auth:org:active-organization-id\",\n);\nexport const ACTIVE_MEMBER_ROLE = Symbol.for(\n \"@nestjs-kit/better-auth:org:active-member-role\",\n);\nexport const ActiveOrganizationId = defineInvocationParam(\n ACTIVE_ORGANIZATION_ID,\n { missing: \"ORGANIZATION_REQUIRED\" },\n);\nexport const ActiveMemberRole = defineInvocationParam(ACTIVE_MEMBER_ROLE, {\n missing: \"MEMBER_ROLE_REQUIRED\",\n});\nconst REF = Symbol.for(\"@nestjs-kit/better-auth:org:ref\");\ntype MarkedRef = OrganizationRef & {\n readonly [REF]?: { kind: \"active\" } | { kind: \"param\"; name: string };\n};\ninterface OrgApi {\n hasPermission(input: {\n headers: Headers;\n body: { organizationId: string; permissions: OrgPermissions };\n }): Promise<{ success: boolean }>;\n getActiveMemberRole(input: {\n headers: Headers;\n query: { organizationId: string };\n }): Promise<{ role?: string | null }>;\n getActiveMember(input: {\n headers: Headers;\n }): Promise<{ organizationId?: string }>;\n}\nexport function organizationRef(\n resolve: (ctx: AuthorizationContext) => unknown | Promise<unknown>,\n options: { missingReason?: string } = {},\n): OrganizationRef {\n return Object.assign((ctx: AuthorizationContext) => resolve(ctx), options);\n}\nexport function activeOrganization(): OrganizationRef {\n return Object.assign(\n organizationRef(\n async (ctx) => {\n const session = (ctx.principal as SessionPrincipal).session as {\n session?: { activeOrganizationId?: unknown };\n };\n const value = session.session?.activeOrganizationId;\n if (value !== undefined) {\n return value;\n }\n if (!(await ctx.auth.hasPlugin(\"custom-session\"))) {\n return undefined;\n }\n try {\n const member = await ctx.memo(\n JSON.stringify([\"org:activeMember\"]),\n () =>\n ctx.auth.run(\n {\n cookies: ctx.cookies,\n inbound: () => ctx.headers,\n internal: true,\n },\n () =>\n (ctx.auth.api as unknown as OrgApi).getActiveMember({\n headers: ctx.headers,\n }),\n ),\n );\n return member?.organizationId;\n } catch (error) {\n if (\n isAPIError(error) &&\n error.statusCode === 400 &&\n (error.body?.code === \"NO_ACTIVE_ORGANIZATION\" ||\n error.body?.code === \"MEMBER_NOT_FOUND\")\n ) {\n return undefined;\n }\n throw error;\n }\n },\n { missingReason: \"NO_ACTIVE_ORGANIZATION\" },\n ),\n { [REF]: { kind: \"active\" as const } },\n );\n}\nexport function fromParam(name: string): OrganizationRef {\n return Object.assign(\n organizationRef((ctx) => ctx.param(name)),\n { [REF]: { kind: \"param\" as const, name } },\n );\n}\nexport function fromHeader(name: string): OrganizationRef {\n return organizationRef((ctx) => ctx.headers.get(name));\n}\nfunction requirements(expressions: readonly RequirementExpr[]): Requirement[] {\n return expressions.flatMap((expression) =>\n \"anyOf\" in expression\n ? requirements(expression.anyOf)\n : \"allOf\" in expression\n ? requirements(expression.allOf)\n : [expression],\n );\n}\nfunction advise(\n ctx: BootAdviceContext,\n policy: AuthorizationPolicy<any, any>,\n): BootAdvice[] {\n const advice: BootAdvice[] = [];\n for (const handler of ctx.handlers) {\n for (const requirement of requirements(handler.plan.requirements)) {\n if (requirement.policy !== policy) {\n continue;\n }\n const ref = (requirement.params as OrgMemberParams)\n .organization as MarkedRef;\n const marker = ref[REF];\n if (marker?.kind === \"active\") {\n const input = handler.inputs.find((name) =>\n [\"orgId\", \"organizationId\", \"organization\", \"orgSlug\"].includes(name),\n );\n if (input) {\n advice.push({\n level: \"warn\",\n code: \"W_ORG_PARAM_IGNORED\",\n message: `${handler.plan.site} checks the active organization but accepts ${input}.`,\n hint:\n input === \"orgSlug\"\n ? \"Map the slug to an ID with organizationRef and auth.api.listOrganizations({ headers }).\"\n : `Use fromParam('${input}').`,\n });\n }\n } else if (\n marker?.kind === \"param\" &&\n !handler.inputs.includes(marker.name)\n ) {\n advice.push({\n level: \"warn\",\n code: \"W_ORG_PARAM_MISSING\",\n message: `${handler.plan.site} reads ${marker.name}, absent from claimed inputs: ${handler.inputs.join(\", \") || \"none\"}.`,\n hint: \"Use the correct input name, a method-level organizationRef, or SkipDefaultRequirements with a method-level requirement.\",\n });\n }\n }\n }\n return advice;\n}\nconst requires = {\n plugins: [\"organization\"],\n principals: [\"session\" as const],\n presentsCredentials: true,\n};\nexport const orgPermissionPolicy: AuthorizationPolicy<\n OrgPermissionParams,\n SessionPrincipal\n> = {\n id: \"better-auth:organization/permission\", // gitleaks:allow: public policy identifier\n requires,\n advise: (ctx) => advise(ctx, orgPermissionPolicy),\n validate({ permissions }) {\n if (\n !Object.keys(permissions).length ||\n Object.values(permissions).some(\n (actions) => !Array.isArray(actions) || !actions.length,\n )\n ) {\n throw new BetterAuthConfigurationError(\n \"EMPTY_PERMISSIONS\",\n \"Organization permissions must contain a resource and actions.\",\n );\n }\n },\n async evaluate({ permissions, organization }, context) {\n const organizationId = await organization(context);\n if (typeof organizationId !== \"string\" || !organizationId.trim()) {\n return {\n effect: \"deny\",\n reason: organization.missingReason ?? \"ORGANIZATION_REQUIRED\",\n };\n }\n const stable = Object.entries(permissions)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([resource, actions]) => [resource, [...actions].sort()]);\n try {\n const result = await context.memo(\n JSON.stringify([\"org:hasPermission\", organizationId, stable]),\n () =>\n context.auth.run(\n {\n cookies: context.cookies,\n inbound: () => context.headers,\n internal: true,\n },\n () =>\n (context.auth.api as unknown as OrgApi).hasPermission({\n headers: context.headers,\n body: { organizationId, permissions },\n }),\n ),\n );\n if (!result.success) {\n return { effect: \"deny\", reason: \"MISSING_PERMISSION\" };\n }\n context.provide(ACTIVE_ORGANIZATION_ID, organizationId);\n return { effect: \"allow\" };\n } catch (error) {\n if (\n isAPIError(error) &&\n error.body?.code === \"USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION\"\n ) {\n return {\n effect: \"deny\",\n reason: \"USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION\",\n };\n }\n throw error;\n }\n },\n};\nexport const orgMemberPolicy: AuthorizationPolicy<\n OrgMemberParams,\n SessionPrincipal\n> = {\n id: \"better-auth:organization/member\",\n requires,\n advise: (ctx) => advise(ctx, orgMemberPolicy),\n async evaluate({ organization }, context) {\n const organizationId = await organization(context);\n if (typeof organizationId !== \"string\" || !organizationId.trim()) {\n return {\n effect: \"deny\",\n reason: organization.missingReason ?? \"ORGANIZATION_REQUIRED\",\n };\n }\n try {\n const result = await context.memo(\n JSON.stringify([\"org:activeMemberRole\", organizationId]),\n () =>\n context.auth.run(\n {\n cookies: context.cookies,\n inbound: () => context.headers,\n internal: true,\n },\n () =>\n (context.auth.api as unknown as OrgApi).getActiveMemberRole({\n headers: context.headers,\n query: { organizationId },\n }),\n ),\n );\n if (typeof result.role !== \"string\" || !result.role.trim()) {\n return {\n effect: \"deny\",\n reason: \"YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION\",\n };\n }\n context.provide(ACTIVE_ORGANIZATION_ID, organizationId);\n context.provide(ACTIVE_MEMBER_ROLE, result.role);\n return { effect: \"allow\" };\n } catch (error) {\n if (\n isAPIError(error) &&\n error.body?.code === \"YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION\"\n ) {\n return {\n effect: \"deny\",\n reason: \"YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION\",\n };\n }\n throw error;\n }\n },\n};\nexport function orgPermission<N extends string = \"default\">(\n permissions: OrgPermissions<N>,\n options: { organization?: OrganizationRef } = {},\n): Requirement<OrgPermissionParams> {\n return {\n policy: orgPermissionPolicy,\n params: {\n permissions: permissions as OrgPermissions,\n organization: options.organization ?? activeOrganization(),\n },\n };\n}\nexport function RequireOrgPermission<N extends string = \"default\">(\n permissions: OrgPermissions<N>,\n options?: { organization?: OrganizationRef },\n): ClassDecorator & MethodDecorator {\n return Require(orgPermission<N>(permissions, options));\n}\nexport function orgMember(\n options: { organization?: OrganizationRef } = {},\n): Requirement<OrgMemberParams> {\n return {\n policy: orgMemberPolicy,\n params: { organization: options.organization ?? activeOrganization() },\n };\n}\nexport function RequireOrgMember(options?: {\n organization?: OrganizationRef;\n}): ClassDecorator & MethodDecorator {\n return Require(orgMember(options));\n}\n"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { Mt as OrgPermissions, f as AuthorizationPolicy, l as AuthorizationContext, ot as Requirement, zt as SessionPrincipal } from "./auth-contracts-Brh_Qko9.cjs";
2
+ //#region src/organization.d.ts
3
+ export interface OrganizationRef {
4
+ (ctx: AuthorizationContext): unknown | Promise<unknown>;
5
+ readonly missingReason?: string;
6
+ }
7
+ export interface OrgPermissionParams {
8
+ readonly permissions: OrgPermissions;
9
+ readonly organization: OrganizationRef;
10
+ }
11
+ export interface OrgMemberParams {
12
+ readonly organization: OrganizationRef;
13
+ }
14
+ export declare const ACTIVE_ORGANIZATION_ID: unique symbol;
15
+ export declare const ACTIVE_MEMBER_ROLE: unique symbol;
16
+ export declare const ActiveOrganizationId: () => ParameterDecorator;
17
+ export declare const ActiveMemberRole: () => ParameterDecorator;
18
+ export declare function organizationRef(resolve: (ctx: AuthorizationContext) => unknown | Promise<unknown>, options?: {
19
+ missingReason?: string;
20
+ }): OrganizationRef;
21
+ export declare function activeOrganization(): OrganizationRef;
22
+ export declare function fromParam(name: string): OrganizationRef;
23
+ export declare function fromHeader(name: string): OrganizationRef;
24
+ export declare const orgPermissionPolicy: AuthorizationPolicy<OrgPermissionParams, SessionPrincipal>;
25
+ export declare const orgMemberPolicy: AuthorizationPolicy<OrgMemberParams, SessionPrincipal>;
26
+ export declare function orgPermission<N extends string = "default">(permissions: OrgPermissions<N>, options?: {
27
+ organization?: OrganizationRef;
28
+ }): Requirement<OrgPermissionParams>;
29
+ export declare function RequireOrgPermission<N extends string = "default">(permissions: OrgPermissions<N>, options?: {
30
+ organization?: OrganizationRef;
31
+ }): ClassDecorator & MethodDecorator;
32
+ export declare function orgMember(options?: {
33
+ organization?: OrganizationRef;
34
+ }): Requirement<OrgMemberParams>;
35
+ export declare function RequireOrgMember(options?: {
36
+ organization?: OrganizationRef;
37
+ }): ClassDecorator & MethodDecorator;
38
+ //#endregion
39
+ export type { OrgPermissions };
40
+ //# sourceMappingURL=organization.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organization.d.cts","names":[],"sources":["../src/organization.ts"],"mappings":";;iBAaiB;GACd,KAAK,iCAAiC;WAC9B;;iBAEM;WACN,aAAa;WACb,cAAc;;iBAER;WACN,cAAc;;qBAEZ;qBAGA;qBAGA,4BAAoB;qBAIpB,wBAAgB;wBAoBb,gBACd,UAAU,KAAK,mCAAmC,kBAClD;EAAW;IACV;wBAGa,sBAAsB;wBAgDtB,UAAU,eAAe;wBAMzB,WAAW,eAAe;qBA4D7B,qBAAqB,oBAChC,qBACA;qBAiEW,iBAAiB,oBAC5B,iBACA;wBAqDc,cAAc,8BAC5B,aAAa,eAAe,IAC5B;EAAW,eAAe;IACzB,YAAY;wBASC,qBAAqB,8BACnC,aAAa,eAAe,IAC5B;EAAY,eAAe;IAC1B,iBAAiB;wBAGJ,UACd;EAAW,eAAe;IACzB,YAAY;wBAMC,iBAAiB;EAC/B,eAAe;IACb,iBAAiB"}
@@ -0,0 +1,40 @@
1
+ import { Mt as OrgPermissions, f as AuthorizationPolicy, l as AuthorizationContext, ot as Requirement, zt as SessionPrincipal } from "./auth-contracts-Cz7C4_Ch.mjs";
2
+ //#region src/organization.d.ts
3
+ export interface OrganizationRef {
4
+ (ctx: AuthorizationContext): unknown | Promise<unknown>;
5
+ readonly missingReason?: string;
6
+ }
7
+ export interface OrgPermissionParams {
8
+ readonly permissions: OrgPermissions;
9
+ readonly organization: OrganizationRef;
10
+ }
11
+ export interface OrgMemberParams {
12
+ readonly organization: OrganizationRef;
13
+ }
14
+ export declare const ACTIVE_ORGANIZATION_ID: unique symbol;
15
+ export declare const ACTIVE_MEMBER_ROLE: unique symbol;
16
+ export declare const ActiveOrganizationId: () => ParameterDecorator;
17
+ export declare const ActiveMemberRole: () => ParameterDecorator;
18
+ export declare function organizationRef(resolve: (ctx: AuthorizationContext) => unknown | Promise<unknown>, options?: {
19
+ missingReason?: string;
20
+ }): OrganizationRef;
21
+ export declare function activeOrganization(): OrganizationRef;
22
+ export declare function fromParam(name: string): OrganizationRef;
23
+ export declare function fromHeader(name: string): OrganizationRef;
24
+ export declare const orgPermissionPolicy: AuthorizationPolicy<OrgPermissionParams, SessionPrincipal>;
25
+ export declare const orgMemberPolicy: AuthorizationPolicy<OrgMemberParams, SessionPrincipal>;
26
+ export declare function orgPermission<N extends string = "default">(permissions: OrgPermissions<N>, options?: {
27
+ organization?: OrganizationRef;
28
+ }): Requirement<OrgPermissionParams>;
29
+ export declare function RequireOrgPermission<N extends string = "default">(permissions: OrgPermissions<N>, options?: {
30
+ organization?: OrganizationRef;
31
+ }): ClassDecorator & MethodDecorator;
32
+ export declare function orgMember(options?: {
33
+ organization?: OrganizationRef;
34
+ }): Requirement<OrgMemberParams>;
35
+ export declare function RequireOrgMember(options?: {
36
+ organization?: OrganizationRef;
37
+ }): ClassDecorator & MethodDecorator;
38
+ //#endregion
39
+ export type { OrgPermissions };
40
+ //# sourceMappingURL=organization.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organization.d.mts","names":[],"sources":["../src/organization.ts"],"mappings":";;iBAaiB;GACd,KAAK,iCAAiC;WAC9B;;iBAEM;WACN,aAAa;WACb,cAAc;;iBAER;WACN,cAAc;;qBAEZ;qBAGA;qBAGA,4BAAoB;qBAIpB,wBAAgB;wBAoBb,gBACd,UAAU,KAAK,mCAAmC,kBAClD;EAAW;IACV;wBAGa,sBAAsB;wBAgDtB,UAAU,eAAe;wBAMzB,WAAW,eAAe;qBA4D7B,qBAAqB,oBAChC,qBACA;qBAiEW,iBAAiB,oBAC5B,iBACA;wBAqDc,cAAc,8BAC5B,aAAa,eAAe,IAC5B;EAAW,eAAe;IACzB,YAAY;wBASC,qBAAqB,8BACnC,aAAa,eAAe,IAC5B;EAAY,eAAe;IAC1B,iBAAiB;wBAGJ,UACd;EAAW,eAAe;IACzB,YAAY;wBAMC,iBAAiB;EAC/B,eAAe;IACb,iBAAiB"}