This repository has been archived by the owner on Jan 3, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 32
/
caveats.ts
115 lines (103 loc) · 2.98 KB
/
caveats.ts
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
113
114
115
import { JsonRpcMiddleware } from 'json-rpc-engine';
import isSubset from 'is-subset';
import equal from 'fast-deep-equal';
import { OcapLdCaveat } from './types/ocap-ld';
import { unauthorized } from './errors';
export type CaveatFunction<T, U> = JsonRpcMiddleware<T, U>;
export type CaveatFunctionGenerator<T, U> = (
caveat: OcapLdCaveat,
) => CaveatFunction<T, U>;
export const caveatFunctions = {
filterResponse,
forceParams,
limitResponseLength,
requireParamsIsSubset,
requireParamsIsSuperset,
};
export const CaveatTypes = Object.keys(caveatFunctions).reduce((map, name) => {
map[name] = name;
return map;
}, {} as Record<string, string>);
/**
* Require that request.params is a subset of or equal to the caveat value.
* Arrays are order-dependent, objects are order-independent.
*/
export function requireParamsIsSubset(
serialized: OcapLdCaveat,
): CaveatFunction<unknown[] | Record<string, unknown>, unknown> {
const { value } = serialized;
return (req, res, next, end): void => {
// Ensure that the params are a subset of or equal to the caveat value
if (!isSubset(value, req.params)) {
res.error = unauthorized({ data: req });
return end(res.error);
}
return next();
};
}
/**
* Require that request.params is a superset of or equal to the caveat value.
* Arrays are order-dependent, objects are order-independent.
*/
export function requireParamsIsSuperset(
serialized: OcapLdCaveat,
): CaveatFunction<unknown[] | Record<string, unknown>, unknown> {
const { value } = serialized;
return (req, res, next, end): void => {
// Ensure that the params are a superset of or equal to the caveat value
if (!isSubset(req.params, value)) {
res.error = unauthorized({ data: req });
return end(res.error);
}
return next();
};
}
/*
* Filters array results deeply.
*/
export function filterResponse(
serialized: OcapLdCaveat,
): CaveatFunction<unknown, unknown[]> {
const { value } = serialized;
return (_req, res, next, _end): void => {
next((done) => {
if (Array.isArray(res.result)) {
res.result = res.result.filter((item) => {
const findResult = value.find((v: unknown) => {
return equal(v, item);
});
return findResult !== undefined;
});
}
done();
});
};
}
/*
* Limits array results to a specific integer length.
*/
export function limitResponseLength(
serialized: OcapLdCaveat,
): CaveatFunction<unknown, unknown[]> {
const { value } = serialized;
return (_req, res, next, _end): void => {
next((done) => {
if (Array.isArray(res.result)) {
res.result = res.result.slice(0, value);
}
done();
});
};
}
/*
* Forces the method to be called with given params.
*/
export function forceParams(
serialized: OcapLdCaveat,
): CaveatFunction<unknown, unknown> {
const { value } = serialized;
return (req, _, next): void => {
req.params = Array.isArray(value) ? [...value] : { ...value };
next();
};
}