@loomcore/api 0.2.50 → 0.2.52
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.
- package/LICENSE +201 -201
- package/dist/__tests__/common-test.utils.d.ts +2 -0
- package/dist/__tests__/common-test.utils.js +7 -1
- package/dist/__tests__/mongo-db.test-database.js +46 -12
- package/dist/__tests__/test-express-app.js +10 -6
- package/dist/controllers/api.controller.d.ts +1 -0
- package/dist/controllers/api.controller.js +12 -10
- package/dist/controllers/auth.controller.js +6 -2
- package/dist/controllers/authorizations.controller.js +2 -2
- package/dist/controllers/features.controller.js +59 -7
- package/dist/controllers/organizations.controller.js +3 -4
- package/dist/controllers/query-api.controller.d.ts +1 -0
- package/dist/controllers/query-api.controller.js +7 -5
- package/dist/controllers/roles.controller.js +59 -7
- package/dist/controllers/user-roles.controller.js +59 -7
- package/dist/controllers/users.controller.d.ts +4 -1
- package/dist/controllers/users.controller.js +87 -11
- package/dist/services/{authorizations.service.d.ts → authorization.service.d.ts} +1 -1
- package/dist/services/{authorizations.service.js → authorization.service.js} +5 -7
- package/dist/services/feature.service.d.ts +6 -0
- package/dist/services/feature.service.js +7 -0
- package/dist/services/index.d.ts +4 -4
- package/dist/services/index.js +4 -4
- package/dist/services/role.service.d.ts +6 -0
- package/dist/services/role.service.js +7 -0
- package/dist/services/user-role.service.d.ts +6 -0
- package/dist/services/user-role.service.js +7 -0
- package/dist/services/user.service.d.ts +4 -7
- package/dist/services/user.service.js +15 -38
- package/dist/utils/auth/attempt-login.util.d.ts +2 -2
- package/dist/utils/auth/attempt-login.util.js +2 -2
- package/dist/utils/auth/authorize-method.util.d.ts +1 -1
- package/dist/utils/auth/index.d.ts +0 -6
- package/dist/utils/auth/index.js +0 -6
- package/dist/utils/auth/request-token-using-refresh-token.util.d.ts +2 -2
- package/dist/utils/auth/request-token-using-refresh-token.util.js +2 -2
- package/dist/utils/auth/reset-password.util.js +5 -3
- package/package.json +1 -1
- package/dist/services/features.service.d.ts +0 -7
- package/dist/services/features.service.js +0 -12
- package/dist/services/roles.service.d.ts +0 -7
- package/dist/services/roles.service.js +0 -12
- package/dist/services/user-roles.service.d.ts +0 -7
- package/dist/services/user-roles.service.js +0 -12
- package/dist/utils/auth/assert-admin-or-feature.util.d.ts +0 -2
- package/dist/utils/auth/assert-admin-or-feature.util.js +0 -8
- package/dist/utils/auth/assert-admin.util.d.ts +0 -2
- package/dist/utils/auth/assert-admin.util.js +0 -7
- package/dist/utils/auth/assert-owner-or-admin.util.d.ts +0 -2
- package/dist/utils/auth/assert-owner-or-admin.util.js +0 -10
- package/dist/utils/auth/assert-user-has-feature.util.d.ts +0 -2
- package/dist/utils/auth/assert-user-has-feature.util.js +0 -18
- package/dist/utils/auth/assert-user-or-admin.util.d.ts +0 -3
- package/dist/utils/auth/assert-user-or-admin.util.js +0 -10
- package/dist/utils/auth/change-password.util.d.ts +0 -6
- package/dist/utils/auth/change-password.util.js +0 -11
|
@@ -1,9 +1,61 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
1
35
|
import { FeatureModelSpec } from '@loomcore/common/models';
|
|
2
|
-
import {
|
|
36
|
+
import { Authorize } from '../decorators/authorize.decorator.js';
|
|
37
|
+
import { FeatureService } from '../services/feature.service.js';
|
|
3
38
|
import { ApiController } from './api.controller.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
39
|
+
let FeaturesController = (() => {
|
|
40
|
+
let _classDecorators = [Authorize('admin')];
|
|
41
|
+
let _classDescriptor;
|
|
42
|
+
let _classExtraInitializers = [];
|
|
43
|
+
let _classThis;
|
|
44
|
+
let _classSuper = ApiController;
|
|
45
|
+
var FeaturesController = class extends _classSuper {
|
|
46
|
+
static { _classThis = this; }
|
|
47
|
+
static {
|
|
48
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
49
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
50
|
+
FeaturesController = _classThis = _classDescriptor.value;
|
|
51
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
52
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
53
|
+
}
|
|
54
|
+
constructor(app, database) {
|
|
55
|
+
const featureService = new FeatureService(database);
|
|
56
|
+
super('features', app, featureService, 'feature', FeatureModelSpec);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return FeaturesController = _classThis;
|
|
60
|
+
})();
|
|
61
|
+
export { FeaturesController };
|
|
@@ -34,7 +34,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
34
34
|
};
|
|
35
35
|
import { BadRequestError } from '../errors/index.js';
|
|
36
36
|
import { OrganizationService } from '../services/index.js';
|
|
37
|
-
import { apiUtils
|
|
37
|
+
import { apiUtils } from '../utils/index.js';
|
|
38
38
|
import { ApiController } from './api.controller.js';
|
|
39
39
|
import { Authorize } from '../decorators/authorize.decorator.js';
|
|
40
40
|
let OrganizationsController = (() => {
|
|
@@ -60,9 +60,8 @@ let OrganizationsController = (() => {
|
|
|
60
60
|
}
|
|
61
61
|
mapRoutes(app) {
|
|
62
62
|
super.mapRoutes(app);
|
|
63
|
-
|
|
64
|
-
app.get(`/api/${this.slug}/get-by-
|
|
65
|
-
app.get(`/api/${this.slug}/get-by-code/:code`, authorize('getByCode'), this.getByCode.bind(this));
|
|
63
|
+
app.get(`/api/${this.slug}/get-by-name/:name`, this.authorize('getByName'), this.getByName.bind(this));
|
|
64
|
+
app.get(`/api/${this.slug}/get-by-code/:code`, this.authorize('getByCode'), this.getByCode.bind(this));
|
|
66
65
|
}
|
|
67
66
|
async getByName(req, res, next) {
|
|
68
67
|
const { name } = req.params;
|
|
@@ -11,6 +11,7 @@ export declare abstract class QueryApiController<T extends IEntity> {
|
|
|
11
11
|
protected publicSpec?: IModelSpec;
|
|
12
12
|
protected idSchema: TSchema;
|
|
13
13
|
protected constructor(slug: string, app: Application, service: IGenericQueryService<T>, resourceName?: string, modelSpec?: IModelSpec, publicSpec?: IModelSpec);
|
|
14
|
+
protected authorize(method: string): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
|
14
15
|
mapRoutes(app: Application): void;
|
|
15
16
|
getAll(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
16
17
|
get(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
@@ -20,12 +20,14 @@ export class QueryApiController {
|
|
|
20
20
|
this.idSchema = getIdSchema();
|
|
21
21
|
this.mapRoutes(app);
|
|
22
22
|
}
|
|
23
|
+
authorize(method) {
|
|
24
|
+
return authorizeMethod(this, method);
|
|
25
|
+
}
|
|
23
26
|
mapRoutes(app) {
|
|
24
|
-
|
|
25
|
-
app.get(`/api/${this.slug}`, authorize('
|
|
26
|
-
app.get(`/api/${this.slug}/
|
|
27
|
-
app.get(`/api/${this.slug}
|
|
28
|
-
app.get(`/api/${this.slug}/:id`, authorize('getById'), this.getById.bind(this));
|
|
27
|
+
app.get(`/api/${this.slug}`, this.authorize('get'), this.get.bind(this));
|
|
28
|
+
app.get(`/api/${this.slug}/all`, this.authorize('getAll'), this.getAll.bind(this));
|
|
29
|
+
app.get(`/api/${this.slug}/count`, this.authorize('getCount'), this.getCount.bind(this));
|
|
30
|
+
app.get(`/api/${this.slug}/:id`, this.authorize('getById'), this.getById.bind(this));
|
|
29
31
|
}
|
|
30
32
|
async getAll(req, res, next) {
|
|
31
33
|
res.set('Content-Type', 'application/json');
|
|
@@ -1,9 +1,61 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
1
35
|
import { RoleModelSpec } from '@loomcore/common/models';
|
|
2
|
-
import {
|
|
36
|
+
import { Authorize } from '../decorators/authorize.decorator.js';
|
|
37
|
+
import { RoleService } from '../services/role.service.js';
|
|
3
38
|
import { ApiController } from './api.controller.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
39
|
+
let RolesController = (() => {
|
|
40
|
+
let _classDecorators = [Authorize('admin')];
|
|
41
|
+
let _classDescriptor;
|
|
42
|
+
let _classExtraInitializers = [];
|
|
43
|
+
let _classThis;
|
|
44
|
+
let _classSuper = ApiController;
|
|
45
|
+
var RolesController = class extends _classSuper {
|
|
46
|
+
static { _classThis = this; }
|
|
47
|
+
static {
|
|
48
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
49
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
50
|
+
RolesController = _classThis = _classDescriptor.value;
|
|
51
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
52
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
53
|
+
}
|
|
54
|
+
constructor(app, database) {
|
|
55
|
+
const roleService = new RoleService(database);
|
|
56
|
+
super('roles', app, roleService, 'role', RoleModelSpec);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return RolesController = _classThis;
|
|
60
|
+
})();
|
|
61
|
+
export { RolesController };
|
|
@@ -1,9 +1,61 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
1
35
|
import { UserRoleModelSpec } from '@loomcore/common/models';
|
|
2
|
-
import {
|
|
36
|
+
import { Authorize } from '../decorators/authorize.decorator.js';
|
|
37
|
+
import { UserRoleService } from '../services/user-role.service.js';
|
|
3
38
|
import { ApiController } from './api.controller.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
39
|
+
let UserRolesController = (() => {
|
|
40
|
+
let _classDecorators = [Authorize('admin')];
|
|
41
|
+
let _classDescriptor;
|
|
42
|
+
let _classExtraInitializers = [];
|
|
43
|
+
let _classThis;
|
|
44
|
+
let _classSuper = ApiController;
|
|
45
|
+
var UserRolesController = class extends _classSuper {
|
|
46
|
+
static { _classThis = this; }
|
|
47
|
+
static {
|
|
48
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
49
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
50
|
+
UserRolesController = _classThis = _classDescriptor.value;
|
|
51
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
52
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
53
|
+
}
|
|
54
|
+
constructor(app, database) {
|
|
55
|
+
const userRoleService = new UserRoleService(database);
|
|
56
|
+
super('user-roles', app, userRoleService, 'user-role', UserRoleModelSpec);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
return UserRolesController = _classThis;
|
|
60
|
+
})();
|
|
61
|
+
export { UserRolesController };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IModelSpec, type IUser } from '@loomcore/common/models';
|
|
2
|
-
import type { Application } from 'express';
|
|
2
|
+
import type { Application, Request, Response } from 'express';
|
|
3
3
|
import type { IDatabase } from '../databases/models/index.js';
|
|
4
4
|
import { UserService } from '../services/index.js';
|
|
5
5
|
import { ApiController } from './api.controller.js';
|
|
@@ -11,4 +11,7 @@ export interface UsersControllerOptions {
|
|
|
11
11
|
export declare class UsersController extends ApiController<IUser> {
|
|
12
12
|
userService: UserService;
|
|
13
13
|
constructor(app: Application, database: IDatabase, options?: UsersControllerOptions);
|
|
14
|
+
mapRoutes(app: Application): void;
|
|
15
|
+
getSelf(req: Request, res: Response): Promise<void>;
|
|
16
|
+
partialUpdateSelf(req: Request, res: Response): Promise<void>;
|
|
14
17
|
}
|
|
@@ -1,14 +1,90 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
+
}
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
1
35
|
import { PublicUserSpec, UserSpec, } from '@loomcore/common/models';
|
|
36
|
+
import { Authorize } from '../decorators/authorize.decorator.js';
|
|
2
37
|
import { UserService } from '../services/index.js';
|
|
38
|
+
import { apiUtils } from '../utils/index.js';
|
|
3
39
|
import { ApiController } from './api.controller.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
40
|
+
let UsersController = (() => {
|
|
41
|
+
let _classDecorators = [Authorize('admin')];
|
|
42
|
+
let _classDescriptor;
|
|
43
|
+
let _classExtraInitializers = [];
|
|
44
|
+
let _classThis;
|
|
45
|
+
let _classSuper = ApiController;
|
|
46
|
+
let _instanceExtraInitializers = [];
|
|
47
|
+
let _getSelf_decorators;
|
|
48
|
+
let _partialUpdateSelf_decorators;
|
|
49
|
+
var UsersController = class extends _classSuper {
|
|
50
|
+
static { _classThis = this; }
|
|
51
|
+
static {
|
|
52
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
53
|
+
_getSelf_decorators = [Authorize()];
|
|
54
|
+
_partialUpdateSelf_decorators = [Authorize()];
|
|
55
|
+
__esDecorate(this, null, _getSelf_decorators, { kind: "method", name: "getSelf", static: false, private: false, access: { has: obj => "getSelf" in obj, get: obj => obj.getSelf }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
56
|
+
__esDecorate(this, null, _partialUpdateSelf_decorators, { kind: "method", name: "partialUpdateSelf", static: false, private: false, access: { has: obj => "partialUpdateSelf" in obj, get: obj => obj.partialUpdateSelf }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
57
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
58
|
+
UsersController = _classThis = _classDescriptor.value;
|
|
59
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
60
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
61
|
+
}
|
|
62
|
+
userService = __runInitializers(this, _instanceExtraInitializers);
|
|
63
|
+
constructor(app, database, options = {
|
|
64
|
+
userService: new UserService(database),
|
|
65
|
+
userSpec: UserSpec,
|
|
66
|
+
publicUserSpec: PublicUserSpec,
|
|
67
|
+
}) {
|
|
68
|
+
super('users', app, options.userService, 'user', options.userSpec, options.publicUserSpec);
|
|
69
|
+
this.userService = options.userService;
|
|
70
|
+
}
|
|
71
|
+
mapRoutes(app) {
|
|
72
|
+
app.get(`/api/${this.slug}/me`, this.authorize('getSelf'), this.getSelf.bind(this));
|
|
73
|
+
app.patch(`/api/${this.slug}/me`, this.authorize('partialUpdateSelf'), this.partialUpdateSelf.bind(this));
|
|
74
|
+
super.mapRoutes(app);
|
|
75
|
+
}
|
|
76
|
+
async getSelf(req, res) {
|
|
77
|
+
res.set('Content-Type', 'application/json');
|
|
78
|
+
const user = await this.userService.getById(req.userContext, req.userContext.user._id);
|
|
79
|
+
apiUtils.apiResponse(res, 200, { data: user }, this.modelSpec, this.publicSpec);
|
|
80
|
+
}
|
|
81
|
+
async partialUpdateSelf(req, res) {
|
|
82
|
+
res.set('Content-Type', 'application/json');
|
|
83
|
+
this.validate(req.body, true);
|
|
84
|
+
const user = await this.userService.partialUpdateById(req.userContext, req.userContext.user._id, req.body);
|
|
85
|
+
apiUtils.apiResponse(res, 200, { data: user }, this.modelSpec, this.publicSpec);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return UsersController = _classThis;
|
|
89
|
+
})();
|
|
90
|
+
export { UsersController };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type IAuthorization, type IUser, type IUserContext } from '@loomcore/common/models';
|
|
2
2
|
import type { IDatabase } from '../databases/index.js';
|
|
3
3
|
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
4
|
-
export declare class
|
|
4
|
+
export declare class AuthorizationService extends MultiTenantApiService<IAuthorization> {
|
|
5
5
|
private userRolesService;
|
|
6
6
|
private featuresService;
|
|
7
7
|
constructor(database: IDatabase);
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { AuthorizationModelSpec, getSystemUserContext, } from '@loomcore/common/models';
|
|
2
|
-
import {
|
|
3
|
-
import { FeaturesService } from './features.service.js';
|
|
2
|
+
import { FeatureService } from './feature.service.js';
|
|
4
3
|
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
5
|
-
import {
|
|
6
|
-
export class
|
|
4
|
+
import { UserRoleService } from './user-role.service.js';
|
|
5
|
+
export class AuthorizationService extends MultiTenantApiService {
|
|
7
6
|
userRolesService;
|
|
8
7
|
featuresService;
|
|
9
8
|
constructor(database) {
|
|
10
9
|
super(database, 'authorizations', 'authorization', AuthorizationModelSpec);
|
|
11
|
-
this.userRolesService = new
|
|
12
|
-
this.featuresService = new
|
|
10
|
+
this.userRolesService = new UserRoleService(database);
|
|
11
|
+
this.featuresService = new FeatureService(database);
|
|
13
12
|
}
|
|
14
13
|
async preProcessEntity(userContext, entity, isCreate, allowId = true) {
|
|
15
|
-
assertUserHasFeature(userContext, ['admin', 'system', 'authorizations']);
|
|
16
14
|
return super.preProcessEntity(userContext, entity, isCreate, allowId);
|
|
17
15
|
}
|
|
18
16
|
async getUserContextFeatures(user) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IFeature } from '@loomcore/common/models';
|
|
2
|
+
import { IDatabase } from '../databases/index.js';
|
|
3
|
+
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
4
|
+
export declare class FeatureService extends MultiTenantApiService<IFeature> {
|
|
5
|
+
constructor(database: IDatabase);
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FeatureModelSpec } from '@loomcore/common/models';
|
|
2
|
+
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
3
|
+
export class FeatureService extends MultiTenantApiService {
|
|
4
|
+
constructor(database) {
|
|
5
|
+
super(database, 'features', 'feature', FeatureModelSpec);
|
|
6
|
+
}
|
|
7
|
+
}
|
package/dist/services/index.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ export * from './organization.service.js';
|
|
|
8
8
|
export * from './organization-domain.service.js';
|
|
9
9
|
export * from './password-reset-token.service.js';
|
|
10
10
|
export * from './refresh-token.service.js';
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './
|
|
13
|
-
export * from './
|
|
14
|
-
export * from './user-
|
|
11
|
+
export * from './authorization.service.js';
|
|
12
|
+
export * from './feature.service.js';
|
|
13
|
+
export * from './role.service.js';
|
|
14
|
+
export * from './user-role.service.js';
|
|
15
15
|
export * from './tenant-query-decorator.js';
|
|
16
16
|
export * from './user.service.js';
|
package/dist/services/index.js
CHANGED
|
@@ -8,9 +8,9 @@ export * from './organization.service.js';
|
|
|
8
8
|
export * from './organization-domain.service.js';
|
|
9
9
|
export * from './password-reset-token.service.js';
|
|
10
10
|
export * from './refresh-token.service.js';
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './
|
|
13
|
-
export * from './
|
|
14
|
-
export * from './user-
|
|
11
|
+
export * from './authorization.service.js';
|
|
12
|
+
export * from './feature.service.js';
|
|
13
|
+
export * from './role.service.js';
|
|
14
|
+
export * from './user-role.service.js';
|
|
15
15
|
export * from './tenant-query-decorator.js';
|
|
16
16
|
export * from './user.service.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IRole } from '@loomcore/common/models';
|
|
2
|
+
import { IDatabase } from '../databases/index.js';
|
|
3
|
+
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
4
|
+
export declare class RoleService extends MultiTenantApiService<IRole> {
|
|
5
|
+
constructor(database: IDatabase);
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RoleModelSpec } from '@loomcore/common/models';
|
|
2
|
+
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
3
|
+
export class RoleService extends MultiTenantApiService {
|
|
4
|
+
constructor(database) {
|
|
5
|
+
super(database, 'roles', 'role', RoleModelSpec);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IUserRole } from '@loomcore/common/models';
|
|
2
|
+
import { IDatabase } from '../databases/index.js';
|
|
3
|
+
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
4
|
+
export declare class UserRoleService extends MultiTenantApiService<IUserRole> {
|
|
5
|
+
constructor(database: IDatabase);
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { UserRoleModelSpec } from '@loomcore/common/models';
|
|
2
|
+
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
3
|
+
export class UserRoleService extends MultiTenantApiService {
|
|
4
|
+
constructor(database) {
|
|
5
|
+
super(database, 'userRoles', 'userRole', UserRoleModelSpec);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import { type IModelSpec, type
|
|
1
|
+
import { type IModelSpec, type IQueryOptions, type IUser, type IUserContext } from '@loomcore/common/models';
|
|
2
2
|
import type { AppIdType } from '@loomcore/common/types';
|
|
3
3
|
import type { IDatabase } from '../databases/models/index.js';
|
|
4
4
|
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
5
5
|
export declare class UserService extends MultiTenantApiService<IUser> {
|
|
6
6
|
constructor(database: IDatabase, modelSpec?: IModelSpec);
|
|
7
|
-
getById(userContext: IUserContext, id: AppIdType): Promise<IUser>;
|
|
8
|
-
get(userContext: IUserContext, queryOptions?: IQueryOptions): Promise<IPagedResult<IUser>>;
|
|
9
|
-
getAll(userContext: IUserContext): Promise<IUser[]>;
|
|
10
|
-
getCount(userContext: IUserContext): Promise<number>;
|
|
11
7
|
fullUpdateById(_userContext: IUserContext, _id: AppIdType, _entity: IUser): Promise<IUser>;
|
|
12
8
|
update(userContext: IUserContext, queryObject: IQueryOptions, entity: Partial<IUser>): Promise<IUser[]>;
|
|
13
9
|
batchUpdate(userContext: IUserContext, entities: Partial<IUser>[]): Promise<IUser[]>;
|
|
14
|
-
partialUpdateById(userContext: IUserContext, id: AppIdType, entity: Partial<IUser
|
|
15
|
-
|
|
10
|
+
partialUpdateById(userContext: IUserContext, id: AppIdType, entity: Partial<IUser>): Promise<IUser>;
|
|
11
|
+
changePassword(userContext: IUserContext, id: AppIdType, password: string): Promise<IUser>;
|
|
16
12
|
preProcessEntity(userContext: IUserContext, entity: Partial<IUser>, isCreate: boolean, allowId?: boolean): Promise<Partial<IUser>>;
|
|
13
|
+
private assertPasswordNotPresent;
|
|
17
14
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { UserSpec, } from '@loomcore/common/models';
|
|
2
2
|
import { BadRequestError, ServerError } from '../errors/index.js';
|
|
3
|
-
import { assertAdmin, assertUserOrAdmin, isAdmin, } from '../utils/auth/index.js';
|
|
4
3
|
import { passwordUtils } from '../utils/password.utils.js';
|
|
5
4
|
import { MultiTenantApiService } from './multi-tenant-api.service.js';
|
|
6
5
|
import moment from 'moment';
|
|
@@ -8,58 +7,31 @@ export class UserService extends MultiTenantApiService {
|
|
|
8
7
|
constructor(database, modelSpec = UserSpec) {
|
|
9
8
|
super(database, 'users', 'user', modelSpec);
|
|
10
9
|
}
|
|
11
|
-
async getById(userContext, id) {
|
|
12
|
-
assertUserOrAdmin(userContext, id);
|
|
13
|
-
return super.getById(userContext, id);
|
|
14
|
-
}
|
|
15
|
-
async get(userContext, queryOptions) {
|
|
16
|
-
assertAdmin(userContext);
|
|
17
|
-
return super.get(userContext, queryOptions);
|
|
18
|
-
}
|
|
19
|
-
async getAll(userContext) {
|
|
20
|
-
assertAdmin(userContext);
|
|
21
|
-
return super.getAll(userContext);
|
|
22
|
-
}
|
|
23
|
-
async getCount(userContext) {
|
|
24
|
-
assertAdmin(userContext);
|
|
25
|
-
return super.getCount(userContext);
|
|
26
|
-
}
|
|
27
10
|
async fullUpdateById(_userContext, _id, _entity) {
|
|
28
11
|
throw new ServerError('User full update is not allowed.');
|
|
29
12
|
}
|
|
30
13
|
async update(userContext, queryObject, entity) {
|
|
31
|
-
|
|
32
|
-
this.assertPasswordUpdateAllowed(userContext, null, entity, false);
|
|
14
|
+
this.assertPasswordNotPresent(entity);
|
|
33
15
|
return super.update(userContext, queryObject, entity);
|
|
34
16
|
}
|
|
35
17
|
async batchUpdate(userContext, entities) {
|
|
36
|
-
assertAdmin(userContext);
|
|
37
18
|
for (const entity of entities) {
|
|
38
|
-
this.
|
|
19
|
+
this.assertPasswordNotPresent(entity);
|
|
39
20
|
}
|
|
40
21
|
return super.batchUpdate(userContext, entities);
|
|
41
22
|
}
|
|
42
|
-
async partialUpdateById(userContext, id, entity
|
|
43
|
-
|
|
44
|
-
this.assertPasswordUpdateAllowed(userContext, id, entity, allowPasswordUpdate);
|
|
23
|
+
async partialUpdateById(userContext, id, entity) {
|
|
24
|
+
this.assertPasswordNotPresent(entity);
|
|
45
25
|
return super.partialUpdateById(userContext, id, entity);
|
|
46
26
|
}
|
|
47
|
-
|
|
48
|
-
if (!
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (!entity.password) {
|
|
27
|
+
async changePassword(userContext, id, password) {
|
|
28
|
+
if (!password) {
|
|
52
29
|
throw new BadRequestError('Password cannot be empty.');
|
|
53
30
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (userContext.user._id !== id) {
|
|
61
|
-
throw new ServerError('You can only update your own password.');
|
|
62
|
-
}
|
|
31
|
+
const updates = {
|
|
32
|
+
password: password,
|
|
33
|
+
};
|
|
34
|
+
return super.partialUpdateById(userContext, id, updates);
|
|
63
35
|
}
|
|
64
36
|
async preProcessEntity(userContext, entity, isCreate, allowId = false) {
|
|
65
37
|
const preparedEntity = await super.preProcessEntity(userContext, entity, isCreate, allowId);
|
|
@@ -74,4 +46,9 @@ export class UserService extends MultiTenantApiService {
|
|
|
74
46
|
}
|
|
75
47
|
return preparedEntity;
|
|
76
48
|
}
|
|
49
|
+
assertPasswordNotPresent(entity) {
|
|
50
|
+
if ('password' in entity) {
|
|
51
|
+
throw new BadRequestError('Cannot update user with password present on the entity.');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
77
54
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ILoginResponse, type IOrganization } from '@loomcore/common/models';
|
|
2
2
|
import type { IDatabase } from '../../databases/models/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { AuthorizationService } from '../../services/authorization.service.js';
|
|
4
4
|
import { UserService } from '../../services/user.service.js';
|
|
5
|
-
export declare function attemptLogin(database: IDatabase, email: string, password: string, deviceId: string, organization: IOrganization | null, userService?: UserService, authorizationsService?:
|
|
5
|
+
export declare function attemptLogin(database: IDatabase, email: string, password: string, deviceId: string, organization: IOrganization | null, userService?: UserService, authorizationsService?: AuthorizationService): Promise<ILoginResponse>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { EmptyUserContext, } from '@loomcore/common/models';
|
|
2
2
|
import { BadRequestError } from '../../errors/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { AuthorizationService } from '../../services/authorization.service.js';
|
|
4
4
|
import { UserService } from '../../services/user.service.js';
|
|
5
5
|
import { passwordUtils } from '../password.utils.js';
|
|
6
6
|
import { logUserIn } from './log-user-in.util.js';
|
|
7
|
-
export async function attemptLogin(database, email, password, deviceId, organization, userService = new UserService(database), authorizationsService = new
|
|
7
|
+
export async function attemptLogin(database, email, password, deviceId, organization, userService = new UserService(database), authorizationsService = new AuthorizationService(database)) {
|
|
8
8
|
const lowerCaseEmail = email.toLowerCase();
|
|
9
9
|
const userContext = {
|
|
10
10
|
...EmptyUserContext,
|