Skip to content

Commit d9a7fd6

Browse files
committed
add method on auth. req. to require permissions
1 parent e974e1b commit d9a7fd6

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

src/Server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class Server<A> extends EventEmitter<Server.Events> {
9595
return;
9696

9797
this.emit("error", e as any);
98-
this.errors._get(ServerErrorRegistry.ErrorCodes.INTERNAL, null)._send(res, this);
98+
await this.errors._get(ServerErrorRegistry.ErrorCodes.INTERNAL, null)._send(res);
9999
return;
100100
}
101101

src/ServerErrorRegistry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class ServerErrorRegistry<A> {
2424

2525
[ServerErrorRegistry.ErrorCodes.PRECONDITION_FAILED]:
2626
new TextResponse("Precondition failed.", 412),
27+
28+
[ServerErrorRegistry.ErrorCodes.NO_PERMISSION]:
29+
new TextResponse("You do not have permission to perform this action.", 403),
2730
};
2831
}
2932

@@ -53,6 +56,7 @@ namespace ServerErrorRegistry {
5356
NO_ROUTE,
5457
INTERNAL,
5558
PRECONDITION_FAILED,
59+
NO_PERMISSION,
5660
}
5761
}
5862

src/auth/AuthenticatedRequest.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import {Request} from "../Request.js";
2+
import {Response, ThrowableResponse} from "../response/index.js";
3+
import {ServerErrorRegistry} from "../ServerErrorRegistry.js";
14
import {Authorisation} from "./Authorisation.js";
25
import {Permissible} from "./Permissible.js";
36
import {Permission} from "./Permission.js";
4-
import {Request} from "../Request.js";
57

68
/**
79
* A request with available {@link Authorisation}.
@@ -32,4 +34,36 @@ export class AuthenticatedRequest<A> extends Request<A> implements Permissible {
3234
public has(permission: Permission): boolean {
3335
return this.authorisation.has(permission);
3436
}
37+
38+
/**
39+
* Require the request to have all the specified permissions.
40+
* @param permissions The required permission.
41+
* @param [response] Throw this response if the request does not have the permission. Defaults to 403 from
42+
* {@link ServerErrorRegistry}.
43+
* @throws {@link ThrowableResponse} If the request does not have the permission.
44+
*/
45+
public require(permissions: Iterable<Permission>, response?: Response<A>): void;
46+
47+
/**
48+
* Require the request to have the specified permission.
49+
* @param permission The required permission.
50+
* @param [response] Throw this response if the request does not have the permission. Defaults to 403 from
51+
* {@link ServerErrorRegistry}.
52+
* @throws {@link ThrowableResponse} If the request does not have the permission.
53+
*/
54+
public require(permission: Permission, response?: Response<A>): void;
55+
public require(required: Permission | Iterable<Permission>, response?: Response<A>): void {
56+
if (required instanceof Permission) {
57+
if (!this.has(required))
58+
throw new ThrowableResponse(
59+
response ?? this.server.errors._get(ServerErrorRegistry.ErrorCodes.NO_PERMISSION, this)
60+
);
61+
}
62+
else for (const permission of required) {
63+
if (!this.has(permission))
64+
throw new ThrowableResponse(
65+
response ?? this.server.errors._get(ServerErrorRegistry.ErrorCodes.NO_PERMISSION, this)
66+
);
67+
}
68+
}
3569
}

src/response/ThrowableResponse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {Response} from "./Response.js";
33
/**
44
* An (error) response that is thrown. Will be caught by the server and sent to the client.
55
*/
6-
export class ThrowableResponse<T extends Response> extends Error {
6+
export class ThrowableResponse<T extends Response<any>> extends Error {
77
public override name = ThrowableResponse.name;
88

99
/**

0 commit comments

Comments
 (0)