@aeriajs/security 0.0.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.
@@ -0,0 +1,180 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _ts_generator(thisArg, body) {
31
+ var f, y, t, g, _ = {
32
+ label: 0,
33
+ sent: function() {
34
+ if (t[0] & 1) throw t[1];
35
+ return t[1];
36
+ },
37
+ trys: [],
38
+ ops: []
39
+ };
40
+ return g = {
41
+ next: verb(0),
42
+ "throw": verb(1),
43
+ "return": verb(2)
44
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
45
+ return this;
46
+ }), g;
47
+ function verb(n) {
48
+ return function(v) {
49
+ return step([
50
+ n,
51
+ v
52
+ ]);
53
+ };
54
+ }
55
+ function step(op) {
56
+ if (f) throw new TypeError("Generator is already executing.");
57
+ while(_)try {
58
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
59
+ if (y = 0, t) op = [
60
+ op[0] & 2,
61
+ t.value
62
+ ];
63
+ switch(op[0]){
64
+ case 0:
65
+ case 1:
66
+ t = op;
67
+ break;
68
+ case 4:
69
+ _.label++;
70
+ return {
71
+ value: op[1],
72
+ done: false
73
+ };
74
+ case 5:
75
+ _.label++;
76
+ y = op[1];
77
+ op = [
78
+ 0
79
+ ];
80
+ continue;
81
+ case 7:
82
+ op = _.ops.pop();
83
+ _.trys.pop();
84
+ continue;
85
+ default:
86
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
87
+ _ = 0;
88
+ continue;
89
+ }
90
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
91
+ _.label = op[1];
92
+ break;
93
+ }
94
+ if (op[0] === 6 && _.label < t[1]) {
95
+ _.label = t[1];
96
+ t = op;
97
+ break;
98
+ }
99
+ if (t && _.label < t[2]) {
100
+ _.label = t[2];
101
+ _.ops.push(op);
102
+ break;
103
+ }
104
+ if (t[2]) _.ops.pop();
105
+ _.trys.pop();
106
+ continue;
107
+ }
108
+ op = body.call(thisArg, _);
109
+ } catch (e) {
110
+ op = [
111
+ 6,
112
+ e
113
+ ];
114
+ y = 0;
115
+ } finally{
116
+ f = t = 0;
117
+ }
118
+ if (op[0] & 5) throw op[1];
119
+ return {
120
+ value: op[0] ? op[1] : void 0,
121
+ done: true
122
+ };
123
+ }
124
+ }
125
+ import { ACErrors } from "@aeriajs/types";
126
+ import { left, right } from "@aeriajs/common";
127
+ export var checkOwnershipRead = function() {
128
+ var _ref = _async_to_generator(function(props, context) {
129
+ var token, description, payload;
130
+ return _ts_generator(this, function(_state) {
131
+ token = context.token, description = context.description;
132
+ payload = Object.assign({}, props.payload);
133
+ if (token.authenticated && description.owned) {
134
+ if (!token.roles.includes("root")) {
135
+ payload.filters.owner = token.sub;
136
+ }
137
+ }
138
+ return [
139
+ 2,
140
+ right(payload)
141
+ ];
142
+ });
143
+ });
144
+ return function checkOwnershipRead(props, context) {
145
+ return _ref.apply(this, arguments);
146
+ };
147
+ }();
148
+ export var checkOwnershipWrite = function() {
149
+ var _ref = _async_to_generator(function(props, context) {
150
+ var token, description, parentId, payload;
151
+ return _ts_generator(this, function(_state) {
152
+ token = context.token, description = context.description;
153
+ parentId = props.parentId;
154
+ payload = Object.assign({}, props.payload);
155
+ if (token.authenticated && description.owned) {
156
+ if (!payload.what._id || description.owned === "always") {
157
+ payload.what.owner = token.sub;
158
+ } else {
159
+ return [
160
+ 2,
161
+ right(payload)
162
+ ];
163
+ }
164
+ }
165
+ if (!payload.what.owner && !parentId && context.description.owned) {
166
+ return [
167
+ 2,
168
+ left(ACErrors.OwnershipError)
169
+ ];
170
+ }
171
+ return [
172
+ 2,
173
+ right(payload)
174
+ ];
175
+ });
176
+ });
177
+ return function checkOwnershipWrite(props, context) {
178
+ return _ref.apply(this, arguments);
179
+ };
180
+ }();
@@ -0,0 +1,3 @@
1
+ import type { SecurityCheckProps, SecurityCheckReadPayload } from './types.js';
2
+ import { ACErrors } from '@aeriajs/types';
3
+ export declare const checkPagination: (props: SecurityCheckProps<SecurityCheckReadPayload>) => Promise<import("@aeriajs/types").Right<SecurityCheckReadPayload> | import("@aeriajs/types").Left<ACErrors.InvalidLimit>>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkPagination = void 0;
4
+ const types_1 = require("@aeriajs/types");
5
+ const common_1 = require("@aeriajs/common");
6
+ const checkPagination = async (props) => {
7
+ const { payload } = props;
8
+ if (payload.limit) {
9
+ if (payload.limit <= 0 || payload.limit > 150) {
10
+ return (0, common_1.left)(types_1.ACErrors.InvalidLimit);
11
+ }
12
+ }
13
+ return (0, common_1.right)(payload);
14
+ };
15
+ exports.checkPagination = checkPagination;
@@ -0,0 +1,149 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _ts_generator(thisArg, body) {
31
+ var f, y, t, g, _ = {
32
+ label: 0,
33
+ sent: function() {
34
+ if (t[0] & 1) throw t[1];
35
+ return t[1];
36
+ },
37
+ trys: [],
38
+ ops: []
39
+ };
40
+ return g = {
41
+ next: verb(0),
42
+ "throw": verb(1),
43
+ "return": verb(2)
44
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
45
+ return this;
46
+ }), g;
47
+ function verb(n) {
48
+ return function(v) {
49
+ return step([
50
+ n,
51
+ v
52
+ ]);
53
+ };
54
+ }
55
+ function step(op) {
56
+ if (f) throw new TypeError("Generator is already executing.");
57
+ while(_)try {
58
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
59
+ if (y = 0, t) op = [
60
+ op[0] & 2,
61
+ t.value
62
+ ];
63
+ switch(op[0]){
64
+ case 0:
65
+ case 1:
66
+ t = op;
67
+ break;
68
+ case 4:
69
+ _.label++;
70
+ return {
71
+ value: op[1],
72
+ done: false
73
+ };
74
+ case 5:
75
+ _.label++;
76
+ y = op[1];
77
+ op = [
78
+ 0
79
+ ];
80
+ continue;
81
+ case 7:
82
+ op = _.ops.pop();
83
+ _.trys.pop();
84
+ continue;
85
+ default:
86
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
87
+ _ = 0;
88
+ continue;
89
+ }
90
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
91
+ _.label = op[1];
92
+ break;
93
+ }
94
+ if (op[0] === 6 && _.label < t[1]) {
95
+ _.label = t[1];
96
+ t = op;
97
+ break;
98
+ }
99
+ if (t && _.label < t[2]) {
100
+ _.label = t[2];
101
+ _.ops.push(op);
102
+ break;
103
+ }
104
+ if (t[2]) _.ops.pop();
105
+ _.trys.pop();
106
+ continue;
107
+ }
108
+ op = body.call(thisArg, _);
109
+ } catch (e) {
110
+ op = [
111
+ 6,
112
+ e
113
+ ];
114
+ y = 0;
115
+ } finally{
116
+ f = t = 0;
117
+ }
118
+ if (op[0] & 5) throw op[1];
119
+ return {
120
+ value: op[0] ? op[1] : void 0,
121
+ done: true
122
+ };
123
+ }
124
+ }
125
+ import { ACErrors } from "@aeriajs/types";
126
+ import { left, right } from "@aeriajs/common";
127
+ export var checkPagination = function() {
128
+ var _ref = _async_to_generator(function(props) {
129
+ var payload;
130
+ return _ts_generator(this, function(_state) {
131
+ payload = props.payload;
132
+ if (payload.limit) {
133
+ if (payload.limit <= 0 || payload.limit > 150) {
134
+ return [
135
+ 2,
136
+ left(ACErrors.InvalidLimit)
137
+ ];
138
+ }
139
+ }
140
+ return [
141
+ 2,
142
+ right(payload)
143
+ ];
144
+ });
145
+ });
146
+ return function checkPagination(props) {
147
+ return _ref.apply(this, arguments);
148
+ };
149
+ }();
@@ -0,0 +1,6 @@
1
+ import type { Context, Description, RateLimitingParams } from '@aeriajs/types';
2
+ export declare enum RateLimitingErrors {
3
+ Unauthenticated = "UNAUTHENTICATED",
4
+ LimitReached = "LIMIT_REACHED"
5
+ }
6
+ export declare const limitRate: <TDescription extends Description>(context: Context<TDescription>, params: RateLimitingParams) => Promise<import("@aeriajs/types").Left<RateLimitingErrors.Unauthenticated> | import("@aeriajs/types").Right<null> | import("@aeriajs/types").Left<RateLimitingErrors.LimitReached>>;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.limitRate = exports.RateLimitingErrors = void 0;
4
+ const common_1 = require("@aeriajs/common");
5
+ var RateLimitingErrors;
6
+ (function (RateLimitingErrors) {
7
+ RateLimitingErrors["Unauthenticated"] = "UNAUTHENTICATED";
8
+ RateLimitingErrors["LimitReached"] = "LIMIT_REACHED";
9
+ })(RateLimitingErrors || (exports.RateLimitingErrors = RateLimitingErrors = {}));
10
+ const getUser = (context) => {
11
+ if (!context.token.authenticated) {
12
+ throw new Error();
13
+ }
14
+ return context.collections.user.model.findOne({
15
+ _id: context.token.sub,
16
+ }, {
17
+ resources_usage: 1,
18
+ });
19
+ };
20
+ const limitRate = async (context, params) => {
21
+ let user;
22
+ if (!context.token.authenticated || !(user = await getUser(context))) {
23
+ return (0, common_1.left)(RateLimitingErrors.Unauthenticated);
24
+ }
25
+ const { increment = 1, limit, scale, } = params;
26
+ const payload = {
27
+ $inc: {
28
+ hits: increment,
29
+ },
30
+ $set: {},
31
+ };
32
+ const usage = user.resources_usage?.get(context.functionPath);
33
+ if (!usage) {
34
+ const entry = await context.collections.resourceUsage.model.insertOne({
35
+ hits: increment,
36
+ });
37
+ await context.collections.user.model.updateOne({
38
+ _id: user._id,
39
+ }, {
40
+ $set: {
41
+ [`resources_usage.${context.functionPath}`]: entry.insertedId,
42
+ },
43
+ });
44
+ return (0, common_1.right)(null);
45
+ }
46
+ if (scale && (new Date().getTime() / 1000 - usage.updated_at.getTime() / 1000 < scale)) {
47
+ return (0, common_1.left)(RateLimitingErrors.LimitReached);
48
+ }
49
+ if (limit && (usage.hits % limit === 0)) {
50
+ payload.$set = {
51
+ last_maximum_reach: new Date(),
52
+ };
53
+ }
54
+ await context.collections.resourceUsage.model.updateOne({
55
+ _id: usage._id,
56
+ }, payload);
57
+ return (0, common_1.right)(null);
58
+ };
59
+ exports.limitRate = limitRate;
@@ -0,0 +1,243 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _define_property(obj, key, value) {
31
+ if (key in obj) {
32
+ Object.defineProperty(obj, key, {
33
+ value: value,
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true
37
+ });
38
+ } else {
39
+ obj[key] = value;
40
+ }
41
+ return obj;
42
+ }
43
+ function _ts_generator(thisArg, body) {
44
+ var f, y, t, g, _ = {
45
+ label: 0,
46
+ sent: function() {
47
+ if (t[0] & 1) throw t[1];
48
+ return t[1];
49
+ },
50
+ trys: [],
51
+ ops: []
52
+ };
53
+ return g = {
54
+ next: verb(0),
55
+ "throw": verb(1),
56
+ "return": verb(2)
57
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
58
+ return this;
59
+ }), g;
60
+ function verb(n) {
61
+ return function(v) {
62
+ return step([
63
+ n,
64
+ v
65
+ ]);
66
+ };
67
+ }
68
+ function step(op) {
69
+ if (f) throw new TypeError("Generator is already executing.");
70
+ while(_)try {
71
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
72
+ if (y = 0, t) op = [
73
+ op[0] & 2,
74
+ t.value
75
+ ];
76
+ switch(op[0]){
77
+ case 0:
78
+ case 1:
79
+ t = op;
80
+ break;
81
+ case 4:
82
+ _.label++;
83
+ return {
84
+ value: op[1],
85
+ done: false
86
+ };
87
+ case 5:
88
+ _.label++;
89
+ y = op[1];
90
+ op = [
91
+ 0
92
+ ];
93
+ continue;
94
+ case 7:
95
+ op = _.ops.pop();
96
+ _.trys.pop();
97
+ continue;
98
+ default:
99
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
100
+ _ = 0;
101
+ continue;
102
+ }
103
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
104
+ _.label = op[1];
105
+ break;
106
+ }
107
+ if (op[0] === 6 && _.label < t[1]) {
108
+ _.label = t[1];
109
+ t = op;
110
+ break;
111
+ }
112
+ if (t && _.label < t[2]) {
113
+ _.label = t[2];
114
+ _.ops.push(op);
115
+ break;
116
+ }
117
+ if (t[2]) _.ops.pop();
118
+ _.trys.pop();
119
+ continue;
120
+ }
121
+ op = body.call(thisArg, _);
122
+ } catch (e) {
123
+ op = [
124
+ 6,
125
+ e
126
+ ];
127
+ y = 0;
128
+ } finally{
129
+ f = t = 0;
130
+ }
131
+ if (op[0] & 5) throw op[1];
132
+ return {
133
+ value: op[0] ? op[1] : void 0,
134
+ done: true
135
+ };
136
+ }
137
+ }
138
+ import { left, right } from "@aeriajs/common";
139
+ export var RateLimitingErrors;
140
+ (function(RateLimitingErrors) {
141
+ RateLimitingErrors["Unauthenticated"] = "UNAUTHENTICATED";
142
+ RateLimitingErrors["LimitReached"] = "LIMIT_REACHED";
143
+ })(RateLimitingErrors || (RateLimitingErrors = {}));
144
+ var getUser = function(context) {
145
+ if (!context.token.authenticated) {
146
+ throw new Error();
147
+ }
148
+ return context.collections.user.model.findOne({
149
+ _id: context.token.sub
150
+ }, {
151
+ resources_usage: 1
152
+ });
153
+ };
154
+ export var limitRate = function() {
155
+ var _ref = _async_to_generator(function(context, params) {
156
+ var _user_resources_usage, user, _tmp, _params_increment, increment, limit, scale, payload, usage, entry;
157
+ return _ts_generator(this, function(_state) {
158
+ switch(_state.label){
159
+ case 0:
160
+ _tmp = !context.token.authenticated;
161
+ if (_tmp) return [
162
+ 3,
163
+ 2
164
+ ];
165
+ return [
166
+ 4,
167
+ getUser(context)
168
+ ];
169
+ case 1:
170
+ _tmp = !(user = _state.sent());
171
+ _state.label = 2;
172
+ case 2:
173
+ if (_tmp) {
174
+ return [
175
+ 2,
176
+ left("UNAUTHENTICATED")
177
+ ];
178
+ }
179
+ _params_increment = params.increment, increment = _params_increment === void 0 ? 1 : _params_increment, limit = params.limit, scale = params.scale;
180
+ payload = {
181
+ $inc: {
182
+ hits: increment
183
+ },
184
+ $set: {}
185
+ };
186
+ usage = (_user_resources_usage = user.resources_usage) === null || _user_resources_usage === void 0 ? void 0 : _user_resources_usage.get(context.functionPath);
187
+ if (!!usage) return [
188
+ 3,
189
+ 5
190
+ ];
191
+ return [
192
+ 4,
193
+ context.collections.resourceUsage.model.insertOne({
194
+ hits: increment
195
+ })
196
+ ];
197
+ case 3:
198
+ entry = _state.sent();
199
+ return [
200
+ 4,
201
+ context.collections.user.model.updateOne({
202
+ _id: user._id
203
+ }, {
204
+ $set: _define_property({}, "resources_usage.".concat(context.functionPath), entry.insertedId)
205
+ })
206
+ ];
207
+ case 4:
208
+ _state.sent();
209
+ return [
210
+ 2,
211
+ right(null)
212
+ ];
213
+ case 5:
214
+ if (scale && new Date().getTime() / 1000 - usage.updated_at.getTime() / 1000 < scale) {
215
+ return [
216
+ 2,
217
+ left("LIMIT_REACHED")
218
+ ];
219
+ }
220
+ if (limit && usage.hits % limit === 0) {
221
+ payload.$set = {
222
+ last_maximum_reach: new Date()
223
+ };
224
+ }
225
+ return [
226
+ 4,
227
+ context.collections.resourceUsage.model.updateOne({
228
+ _id: usage._id
229
+ }, payload)
230
+ ];
231
+ case 6:
232
+ _state.sent();
233
+ return [
234
+ 2,
235
+ right(null)
236
+ ];
237
+ }
238
+ });
239
+ });
240
+ return function limitRate(context, params) {
241
+ return _ref.apply(this, arguments);
242
+ };
243
+ }();
@@ -0,0 +1,17 @@
1
+ import type { Context, Either, GetAllPayload, InsertPayload, ACErrors } from '@aeriajs/types';
2
+ export type SecurityCheckReadPayload = {
3
+ filters: Record<string, any>;
4
+ sort?: Record<string, any>;
5
+ limit?: number;
6
+ offset?: number;
7
+ };
8
+ export type SecurityCheckWritePayload = {
9
+ what: Record<string, any>;
10
+ };
11
+ export type SecurityCheckProps<TPayload extends Record<string, any> = any> = {
12
+ propertyName?: string;
13
+ parentId?: string;
14
+ childId?: string;
15
+ payload: TPayload;
16
+ };
17
+ export type SecurityCheck = (props: SecurityCheckProps, context: Context) => Promise<Either<ACErrors, GetAllPayload<any> | InsertPayload<any>>>;
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/types.mjs ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/use.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Context, Description, GetAllPayload, InsertPayload } from '@aeriajs/types';
2
+ export declare const useSecurity: <TDescription extends Description>(context: Context<TDescription>) => {
3
+ beforeRead: <TPayload extends Partial<GetAllPayload<any>>>(payload?: TPayload | undefined) => Promise<import("@aeriajs/types").Left<import("@aeriajs/types").ACErrors> | import("@aeriajs/types").Right<Record<string, any>>>;
4
+ beforeWrite: <TPayload_1 extends Partial<InsertPayload<any>>>(payload?: TPayload_1 | undefined) => Promise<import("@aeriajs/types").Left<import("@aeriajs/types").ACErrors> | import("@aeriajs/types").Right<Record<string, any>>>;
5
+ };