bazis 0.109.1 → 0.110.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.
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ServiceScope } from "../../di";
|
|
2
|
+
import { HttpSetupError } from "../Errors/HttpError";
|
|
2
3
|
|
|
3
4
|
// Same one-line polyfill as the rest of the HTTP module: Bun executes TC39
|
|
4
5
|
// decorators natively, but Symbol.metadata may be missing in the runtime.
|
|
@@ -46,6 +47,8 @@ interface AuthActionMeta {
|
|
|
46
47
|
allowAnonymous?: boolean;
|
|
47
48
|
/** Declaration made on this exact class/method metadata object. */
|
|
48
49
|
declaration?: "authorize" | "anonymous";
|
|
50
|
+
/** Both `@Authorize` and `@AllowAnonymous` were declared here. */
|
|
51
|
+
conflict?: true;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
interface AuthControllerMeta {
|
|
@@ -53,6 +56,8 @@ interface AuthControllerMeta {
|
|
|
53
56
|
allowAnonymous?: boolean;
|
|
54
57
|
/** Declaration made on this exact class metadata object. */
|
|
55
58
|
declaration?: "authorize" | "anonymous";
|
|
59
|
+
/** Both `@Authorize` and `@AllowAnonymous` were declared on the class. */
|
|
60
|
+
conflict?: true;
|
|
56
61
|
actions: Map<string | symbol, AuthActionMeta>;
|
|
57
62
|
}
|
|
58
63
|
|
|
@@ -105,8 +110,15 @@ function ownActionMeta(metadata: object, methodName: string | symbol): AuthActio
|
|
|
105
110
|
return action;
|
|
106
111
|
}
|
|
107
112
|
|
|
113
|
+
// The other declaration on the same class or method: each would silently undo
|
|
114
|
+
// the other and the decorator order would decide. Reported when routes are built.
|
|
115
|
+
function markConflict(target: { declaration?: "authorize" | "anonymous"; conflict?: true }, declaration: "authorize" | "anonymous"): void {
|
|
116
|
+
if (target.declaration !== undefined && target.declaration !== declaration) target.conflict = true;
|
|
117
|
+
}
|
|
118
|
+
|
|
108
119
|
export function setControllerAuthorize(metadata: object, options: AuthorizeOptions): void {
|
|
109
120
|
const meta = ownMeta(metadata);
|
|
121
|
+
markConflict(meta, "authorize");
|
|
110
122
|
meta.authorize = meta.declaration === "authorize" && meta.authorize
|
|
111
123
|
? { checks: [...options.checks, ...meta.authorize.checks] }
|
|
112
124
|
: options;
|
|
@@ -116,6 +128,7 @@ export function setControllerAuthorize(metadata: object, options: AuthorizeOptio
|
|
|
116
128
|
|
|
117
129
|
export function setControllerAllowAnonymous(metadata: object): void {
|
|
118
130
|
const meta = ownMeta(metadata);
|
|
131
|
+
markConflict(meta, "anonymous");
|
|
119
132
|
meta.allowAnonymous = true;
|
|
120
133
|
meta.declaration = "anonymous";
|
|
121
134
|
delete meta.authorize;
|
|
@@ -123,6 +136,7 @@ export function setControllerAllowAnonymous(metadata: object): void {
|
|
|
123
136
|
|
|
124
137
|
export function setActionAuthorize(metadata: object, methodName: string | symbol, options: AuthorizeOptions): void {
|
|
125
138
|
const action = ownActionMeta(metadata, methodName);
|
|
139
|
+
markConflict(action, "authorize");
|
|
126
140
|
action.authorize = action.declaration === "authorize" && action.authorize
|
|
127
141
|
? { checks: [...options.checks, ...action.authorize.checks] }
|
|
128
142
|
: options;
|
|
@@ -132,6 +146,7 @@ export function setActionAuthorize(metadata: object, methodName: string | symbol
|
|
|
132
146
|
|
|
133
147
|
export function setActionAllowAnonymous(metadata: object, methodName: string | symbol): void {
|
|
134
148
|
const action = ownActionMeta(metadata, methodName);
|
|
149
|
+
markConflict(action, "anonymous");
|
|
135
150
|
action.allowAnonymous = true;
|
|
136
151
|
action.declaration = "anonymous";
|
|
137
152
|
delete action.authorize;
|
|
@@ -153,6 +168,7 @@ export interface ResolvedAuthorizeMeta {
|
|
|
153
168
|
*
|
|
154
169
|
* Inheritance is different: a subclass's own class-level declaration replaces
|
|
155
170
|
* the base class's, and an overriding method's declaration replaces the base method's.
|
|
171
|
+
* Both decorators on the same class or method throw `HttpSetupError`.
|
|
156
172
|
*/
|
|
157
173
|
export function resolveAuthorizeMeta(ctor: object, methodName: string | symbol): ResolvedAuthorizeMeta {
|
|
158
174
|
const metadata = (ctor as { [key: symbol]: unknown })[Symbol.metadata as unknown as symbol] as
|
|
@@ -163,7 +179,20 @@ export function resolveAuthorizeMeta(ctor: object, methodName: string | symbol):
|
|
|
163
179
|
return { allowAnonymous: false };
|
|
164
180
|
}
|
|
165
181
|
|
|
182
|
+
const owner = (ctor as { readonly name?: string }).name || "Controller";
|
|
183
|
+
if (meta.conflict) {
|
|
184
|
+
throw new HttpSetupError(
|
|
185
|
+
`${owner} has both @AllowAnonymous() and @Authorize(...) on the class: the result would depend on the decorator order. `
|
|
186
|
+
+ "Keep one; to open single methods of a protected class, put @AllowAnonymous() on them.",
|
|
187
|
+
);
|
|
188
|
+
}
|
|
166
189
|
const action = meta.actions.get(methodName);
|
|
190
|
+
if (action?.conflict) {
|
|
191
|
+
throw new HttpSetupError(
|
|
192
|
+
`${owner}.${String(methodName)} has both @AllowAnonymous() and @Authorize(...): the result would depend on the decorator order. `
|
|
193
|
+
+ "Keep @Authorize(...) to protect the route, or @AllowAnonymous() to open it.",
|
|
194
|
+
);
|
|
195
|
+
}
|
|
167
196
|
if (action?.allowAnonymous) {
|
|
168
197
|
return { allowAnonymous: true };
|
|
169
198
|
}
|
|
@@ -232,7 +232,7 @@ export class CodexAppServerClient implements CodexClient {
|
|
|
232
232
|
if (method === "account/updated") this.modelCache = undefined;
|
|
233
233
|
}, () => { this.clearLogin(); this.modelCache = undefined; });
|
|
234
234
|
const initialized = await client.request("initialize", {
|
|
235
|
-
clientInfo: { name: "bazis", title: "Bazis", version: "0.
|
|
235
|
+
clientInfo: { name: "bazis", title: "Bazis", version: "0.110.0" }, capabilities: { experimentalApi: true },
|
|
236
236
|
}, 15_000, signal);
|
|
237
237
|
if (resolve(text(initialized.codexHome, 4096)) !== this.paths.home) throw new CodexError("PROTOCOL_ERROR");
|
|
238
238
|
client.notify("initialized");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bazis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.110.0",
|
|
4
4
|
"description": "Modular backend framework for Bun in TypeScript: DI wired by codegen, HTTP, a PostgreSQL ORM, JWT, WebSocket, agents and a CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Alexander Alenin",
|