forked from bogeeee/restfuncs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathControlService.ts
More file actions
112 lines (88 loc) · 3.3 KB
/
Copy pathControlService.ts
File metadata and controls
112 lines (88 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import {ServerSessionOptions, ServerSession, remote} from "restfuncs-server";
import session from "express-session";
import express from "express"
import _ from "underscore";
import {shieldTokenAgainstBREACH_unwrap} from "restfuncs-server/Util"
import {TestsService} from "./TestsService.js";
export class ControlService extends ServerSession {
static options: ServerSessionOptions = {allowedOrigins: "all", exposeErrors: true, devDisableSecurity: true}
@remote()
async resetSession() {
this.destroy()
}
static lock?: ExternalPromise<void>
@remote()
async getLock() {
if(ControlService.lock) {
return await ControlService.lock;
}
ControlService.lock = new ExternalPromise()
}
@remote()
releaseLock() {
ControlService.lock?.resolve()
ControlService.lock = undefined;
}
@remote()
async getCorsReadTokenForService(id: string) {
// @ts-ignore
return this.getServiceClass(id).getOrCreateSecurityToken(this.call.req!.session, "corsReadToken")
}
@remote()
async getCsrfTokenForService(id: string) {
if(!this.call.req) {
throw new Error("Not called by http")
}
const ServiceClass = this.getServiceClass(id);
return ServiceClass.getCsrfToken(this.call.req, this.call.res!)
}
private getServiceClass(id: string): any /* used any because of an error when typescript-rtti follows/includes (typeof ServerSession).typiaRuntime */ {
let server = this.clazz.server;
const ServiceClass = server.serverSessionClasses.get(id);
if (!ServiceClass) {
throw new Error(`No class found with id: ${id}`);
}
return ServiceClass;
}
/**
* The browser code does not have direct access to shieldTokenAgainstBREACH_unwrap or node's Buffer class
* @param shieldedToken
*/
@remote()
async shieldTokenAgainstBREACH_unwrap(shieldedToken: string): Promise<string> {
return shieldTokenAgainstBREACH_unwrap(shieldedToken).toString("hex");
}
@remote()
clearLastCallWasSimpleRequest() {
TestsService.lastCallWasSimpleRequest = undefined
}
}
/**
* Exposes the resolve and reject methods to the outside
*/
class ExternalPromise<T> implements Promise<T>{
private promise: Promise<T>;
resolve!: (value: T | PromiseLike<T>) => void;
reject!: (reason?: any) => void;
constructor() {
this.promise = new Promise<T>((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
): Promise<TResult1 | TResult2> {
return this.promise.then(onFulfilled, onRejected);
}
catch<TResult = never>(
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
): Promise<T | TResult> {
return this.promise.catch(onRejected);
}
finally(onFinally?: (() => void) | null): Promise<T> {
return this.promise.finally(onFinally);
}
readonly [Symbol.toStringTag]: string = "WrappedPromise"; // Must offer this when implementing Promise. Hopefully this is a proper value
}