@atls/nestjs-keto 0.0.5 → 0.0.7
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/dist/decorators/get-guarding-relation.helper.d.ts +2 -0
- package/dist/decorators/get-guarding-relation.helper.js +2 -0
- package/dist/decorators/guarded-by-keto.constants.d.ts +1 -0
- package/dist/decorators/guarded-by-keto.constants.js +1 -0
- package/dist/decorators/guarded-by-keto.decorator.d.ts +2 -0
- package/dist/decorators/guarded-by-keto.decorator.js +3 -0
- package/dist/decorators/guarded-by-keto.interfaces.d.ts +5 -0
- package/dist/decorators/guarded-by-keto.interfaces.js +1 -0
- package/dist/decorators/index.d.ts +5 -1
- package/dist/decorators/index.js +3 -17
- package/dist/exceptions/exception-message.constants.d.ts +4 -0
- package/dist/exceptions/exception-message.constants.js +5 -0
- package/dist/exceptions/general.exception.d.ts +5 -0
- package/dist/exceptions/general.exception.js +7 -0
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.js +2 -0
- package/dist/exceptions/relation-tuple-invalid.exception.d.ts +5 -0
- package/dist/exceptions/relation-tuple-invalid.exception.js +7 -0
- package/dist/guards/index.d.ts +1 -1
- package/dist/guards/index.js +1 -17
- package/dist/guards/keto.guard.d.ts +11 -0
- package/dist/guards/keto.guard.js +64 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -21
- package/dist/module/index.d.ts +3 -0
- package/dist/module/index.js +3 -0
- package/dist/module/keto-module.interfaces.d.ts +30 -0
- package/dist/module/keto-module.interfaces.js +1 -0
- package/dist/module/keto.constants.d.ts +5 -0
- package/dist/module/keto.constants.js +5 -0
- package/dist/module/keto.module.d.ts +9 -0
- package/dist/module/keto.module.js +63 -0
- package/dist/module/keto.providers.d.ts +4 -0
- package/dist/module/keto.providers.js +38 -0
- package/dist/services/index.d.ts +5 -1
- package/dist/services/index.js +5 -17
- package/dist/services/keto-configuration.service.d.ts +6 -0
- package/dist/services/keto-configuration.service.js +29 -0
- package/dist/services/keto-permissions.service.d.ts +6 -0
- package/dist/services/keto-permissions.service.js +30 -0
- package/dist/services/keto-read-client.service.d.ts +7 -0
- package/dist/services/keto-read-client.service.js +59 -0
- package/dist/services/keto-relations.service.d.ts +6 -0
- package/dist/services/keto-relations.service.js +30 -0
- package/dist/services/keto-write-client.service.d.ts +11 -0
- package/dist/services/keto-write-client.service.js +68 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/relation-tuple-converter.d.ts +19 -0
- package/dist/utils/relation-tuple-converter.js +88 -0
- package/package.json +40 -15
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -5
- package/dist/decorators/access-policy.decorator.d.ts +0 -1
- package/dist/decorators/access-policy.decorator.js +0 -7
- package/dist/guards/keto-access-control.guard.d.ts +0 -13
- package/dist/guards/keto-access-control.guard.js +0 -61
- package/dist/keto.module.d.ts +0 -4
- package/dist/keto.module.js +0 -40
- package/dist/services/resource.service.d.ts +0 -7
- package/dist/services/resource.service.js +0 -54
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const GUARDED_BY_METADATA_KEY: unique symbol;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const GUARDED_BY_METADATA_KEY = Symbol('GuardedByKeto');
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CustomDecorator } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
export type GetGuardingRelationTuple = (reflector: Reflector, handler: Parameters<Reflector['get']>[1]) => string | ReplaceGenerator;
|
|
4
|
+
export type ReplaceGenerator = (value: string) => string;
|
|
5
|
+
export type GuardedByKetoFunction = (relationTuple: string | ReplaceGenerator) => CustomDecorator<symbol>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './guarded-by-keto.decorator.js';
|
|
2
|
+
export { GuardedByKetoFunction } from './guarded-by-keto.interfaces.js';
|
|
3
|
+
export { GetGuardingRelationTuple } from './guarded-by-keto.interfaces.js';
|
|
4
|
+
export { GUARDED_BY_METADATA_KEY } from './guarded-by-keto.constants.js';
|
|
5
|
+
export { getGuardingRelationTuple } from './get-guarding-relation.helper.js';
|
package/dist/decorators/index.js
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./access-policy.decorator"), exports);
|
|
1
|
+
export * from "./guarded-by-keto.decorator.js";
|
|
2
|
+
export { GUARDED_BY_METADATA_KEY } from "./guarded-by-keto.constants.js";
|
|
3
|
+
export { getGuardingRelationTuple } from "./get-guarding-relation.helper.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export var KetoExceptionMessage;
|
|
2
|
+
(function (KetoExceptionMessage) {
|
|
3
|
+
KetoExceptionMessage["GENERAL_ERROR"] = "General Keto error";
|
|
4
|
+
KetoExceptionMessage["RELATION_TUPLE_INVALID"] = "Provided relation tuple is invalid";
|
|
5
|
+
})(KetoExceptionMessage || (KetoExceptionMessage = {}));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AssertionError } from 'node:assert';
|
|
2
|
+
import { KetoExceptionMessage } from './exception-message.constants.js';
|
|
3
|
+
export class KetoGeneralException extends AssertionError {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super({ message: `${KetoExceptionMessage.GENERAL_ERROR}: ${message}` });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AssertionError } from 'node:assert';
|
|
2
|
+
import { KetoExceptionMessage } from './exception-message.constants.js';
|
|
3
|
+
export class KetoRelationTupleInvalidException extends AssertionError {
|
|
4
|
+
constructor() {
|
|
5
|
+
super({ message: `${KetoExceptionMessage.RELATION_TUPLE_INVALID}` });
|
|
6
|
+
}
|
|
7
|
+
}
|
package/dist/guards/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './keto
|
|
1
|
+
export * from './keto.guard.js';
|
package/dist/guards/index.js
CHANGED
|
@@ -1,17 +1 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./keto-access-control.guard"), exports);
|
|
1
|
+
export * from "./keto.guard.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { CanActivate } from '@nestjs/common';
|
|
3
|
+
import { Reflector } from '@nestjs/core';
|
|
4
|
+
import { KetoReadClientService } from '../services/index.js';
|
|
5
|
+
export declare class KetoGuard implements CanActivate {
|
|
6
|
+
private readonly reflector;
|
|
7
|
+
private readonly ketoReadClient;
|
|
8
|
+
constructor(reflector: Reflector, ketoReadClient: KetoReadClientService);
|
|
9
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
10
|
+
private getUserId;
|
|
11
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
14
|
+
import { Injectable } from '@nestjs/common';
|
|
15
|
+
import { Reflector } from '@nestjs/core';
|
|
16
|
+
import { GqlExecutionContext } from '@nestjs/graphql';
|
|
17
|
+
import { KetoGeneralException } from '../exceptions/index.js';
|
|
18
|
+
import { KETO_READ_CLIENT } from '../module/index.js';
|
|
19
|
+
import { KetoReadClientService } from '../services/index.js';
|
|
20
|
+
import { RelationTupleConverter } from '../utils/index.js';
|
|
21
|
+
import { getGuardingRelationTuple } from '../decorators/index.js';
|
|
22
|
+
let KetoGuard = class KetoGuard {
|
|
23
|
+
reflector;
|
|
24
|
+
ketoReadClient;
|
|
25
|
+
constructor(reflector, ketoReadClient) {
|
|
26
|
+
this.reflector = reflector;
|
|
27
|
+
this.ketoReadClient = ketoReadClient;
|
|
28
|
+
}
|
|
29
|
+
async canActivate(context) {
|
|
30
|
+
try {
|
|
31
|
+
const userId = this.getUserId(context);
|
|
32
|
+
if (!userId)
|
|
33
|
+
return false;
|
|
34
|
+
const relationTuple = getGuardingRelationTuple(this.reflector, context.getHandler());
|
|
35
|
+
if (relationTuple === null)
|
|
36
|
+
return false;
|
|
37
|
+
const converter = new RelationTupleConverter(relationTuple, userId);
|
|
38
|
+
const tuple = converter.run();
|
|
39
|
+
return await this.ketoReadClient.validateRelationTuple(tuple);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw new KetoGeneralException(err.toString());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
getUserId(ctx) {
|
|
46
|
+
const contextType = ctx.getType();
|
|
47
|
+
let metadata;
|
|
48
|
+
switch (contextType) {
|
|
49
|
+
case 'graphql':
|
|
50
|
+
metadata = GqlExecutionContext.create(ctx).getContext();
|
|
51
|
+
return metadata.user;
|
|
52
|
+
default:
|
|
53
|
+
metadata = ctx.switchToHttp().getRequest();
|
|
54
|
+
return metadata.get('x_user') ?? metadata.get('x-user');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
KetoGuard = __decorate([
|
|
59
|
+
Injectable(),
|
|
60
|
+
__param(1, Inject(KETO_READ_CLIENT)),
|
|
61
|
+
__metadata("design:paramtypes", [Reflector,
|
|
62
|
+
KetoReadClientService])
|
|
63
|
+
], KetoGuard);
|
|
64
|
+
export { KetoGuard };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from '
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
1
|
+
export * from './module/index.js';
|
|
2
|
+
export * from '@ory/keto-client';
|
|
3
|
+
export * from './guards/index.js';
|
|
4
|
+
export * from './decorators/index.js';
|
|
5
|
+
export * from './utils/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./keto.module"), exports);
|
|
18
|
-
__exportStar(require("./constants"), exports);
|
|
19
|
-
__exportStar(require("./decorators"), exports);
|
|
20
|
-
__exportStar(require("./services"), exports);
|
|
21
|
-
__exportStar(require("./guards"), exports);
|
|
1
|
+
export * from "./module/index.js";
|
|
2
|
+
export * from "@ory/keto-client";
|
|
3
|
+
export * from "./guards/index.js";
|
|
4
|
+
export * from "./decorators/index.js";
|
|
5
|
+
export * from "./utils/index.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Type } from '@nestjs/common/interfaces';
|
|
2
|
+
import { ModuleMetadata } from '@nestjs/common/interfaces';
|
|
3
|
+
import { ConfigurationParameters } from '@ory/keto-client';
|
|
4
|
+
import { SubjectSet } from '@ory/keto-client';
|
|
5
|
+
export interface KetoModuleOptions extends ConfigurationParameters {
|
|
6
|
+
global?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface KetoOptionsFactory {
|
|
9
|
+
createKetoOptions(): Promise<KetoModuleOptions> | KetoModuleOptions;
|
|
10
|
+
}
|
|
11
|
+
export interface KetoModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
12
|
+
useExisting?: Type<KetoOptionsFactory>;
|
|
13
|
+
useClass?: Type<KetoOptionsFactory>;
|
|
14
|
+
useFactory?: (...args: any[]) => Promise<KetoModuleOptions> | KetoModuleOptions;
|
|
15
|
+
inject?: any[];
|
|
16
|
+
global?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export type RelationShipTuple = RelationShipTupleWithId | RelationShipTupleWithSet;
|
|
19
|
+
export type RelationShipTupleWithId = {
|
|
20
|
+
namespace: string;
|
|
21
|
+
object: string;
|
|
22
|
+
relation: string;
|
|
23
|
+
subject_id: string;
|
|
24
|
+
};
|
|
25
|
+
export type RelationShipTupleWithSet = {
|
|
26
|
+
namespace: string;
|
|
27
|
+
object: string;
|
|
28
|
+
relation: string;
|
|
29
|
+
subject_set: SubjectSet;
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const KETO_MODULE_CONFIGURATION = "KETO_MODULE_CONFIGURATION";
|
|
2
|
+
export declare const KETO_READ_CLIENT = "KETO_READ_CLIENT";
|
|
3
|
+
export declare const KETO_PERMISSIONS = "KETO_PERMISSIONS";
|
|
4
|
+
export declare const KETO_WRITE_CLIENT = "KETO_WRITE_CLIENT";
|
|
5
|
+
export declare const KETO_RELATIONS = "KETO_RELATIONS";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const KETO_MODULE_CONFIGURATION = 'KETO_MODULE_CONFIGURATION';
|
|
2
|
+
export const KETO_READ_CLIENT = 'KETO_READ_CLIENT';
|
|
3
|
+
export const KETO_PERMISSIONS = 'KETO_PERMISSIONS';
|
|
4
|
+
export const KETO_WRITE_CLIENT = 'KETO_WRITE_CLIENT';
|
|
5
|
+
export const KETO_RELATIONS = 'KETO_RELATIONS';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { KetoModuleAsyncOptions } from './keto-module.interfaces.js';
|
|
3
|
+
import { KetoModuleOptions } from './keto-module.interfaces.js';
|
|
4
|
+
export declare class KetoModule {
|
|
5
|
+
static register(options: KetoModuleOptions): DynamicModule;
|
|
6
|
+
static registerAsync(options: KetoModuleAsyncOptions): DynamicModule;
|
|
7
|
+
private static createAsyncProviders;
|
|
8
|
+
private static createAsyncOptionsProvider;
|
|
9
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var KetoModule_1;
|
|
8
|
+
import { Module } from '@nestjs/common';
|
|
9
|
+
import { KETO_MODULE_CONFIGURATION } from './keto.constants.js';
|
|
10
|
+
import { createKetoExportsProvider } from './keto.providers.js';
|
|
11
|
+
import { createKetoConfigurationProvider } from './keto.providers.js';
|
|
12
|
+
let KetoModule = KetoModule_1 = class KetoModule {
|
|
13
|
+
static register(options) {
|
|
14
|
+
const optionsProvider = createKetoConfigurationProvider(options);
|
|
15
|
+
const exportsProvider = createKetoExportsProvider();
|
|
16
|
+
return {
|
|
17
|
+
global: options?.global ?? true,
|
|
18
|
+
module: KetoModule_1,
|
|
19
|
+
providers: [...optionsProvider, ...exportsProvider],
|
|
20
|
+
exports: exportsProvider,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
static registerAsync(options) {
|
|
24
|
+
const exportsProvider = createKetoExportsProvider();
|
|
25
|
+
return {
|
|
26
|
+
global: options?.global ?? true,
|
|
27
|
+
module: KetoModule_1,
|
|
28
|
+
imports: options.imports || [],
|
|
29
|
+
providers: [...this.createAsyncProviders(options), ...exportsProvider],
|
|
30
|
+
exports: exportsProvider,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
static createAsyncProviders(options) {
|
|
34
|
+
if (options.useExisting || options.useFactory) {
|
|
35
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
36
|
+
}
|
|
37
|
+
return [
|
|
38
|
+
this.createAsyncOptionsProvider(options),
|
|
39
|
+
{
|
|
40
|
+
provide: options.useClass,
|
|
41
|
+
useClass: options.useClass,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
static createAsyncOptionsProvider(options) {
|
|
46
|
+
if (options.useFactory) {
|
|
47
|
+
return {
|
|
48
|
+
provide: KETO_MODULE_CONFIGURATION,
|
|
49
|
+
useFactory: options.useFactory,
|
|
50
|
+
inject: options.inject || [],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
provide: KETO_MODULE_CONFIGURATION,
|
|
55
|
+
useFactory: (optionsFactory) => optionsFactory.createKetoOptions(),
|
|
56
|
+
inject: [options.useExisting || options.useClass],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
KetoModule = KetoModule_1 = __decorate([
|
|
61
|
+
Module({})
|
|
62
|
+
], KetoModule);
|
|
63
|
+
export { KetoModule };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Provider } from '@nestjs/common';
|
|
2
|
+
import { KetoModuleOptions } from './keto-module.interfaces.js';
|
|
3
|
+
export declare const createKetoConfigurationProvider: (options: KetoModuleOptions) => Provider[];
|
|
4
|
+
export declare const createKetoExportsProvider: () => Provider[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { KetoConfigurationService } from '../services/index.js';
|
|
2
|
+
import { KetoPermissionsService } from '../services/index.js';
|
|
3
|
+
import { KetoWriteClientService } from '../services/index.js';
|
|
4
|
+
import { KetoReadClientService } from '../services/index.js';
|
|
5
|
+
import { KetoRelationsService } from '../services/index.js';
|
|
6
|
+
import { KETO_RELATIONS } from './keto.constants.js';
|
|
7
|
+
import { KETO_PERMISSIONS } from './keto.constants.js';
|
|
8
|
+
import { KETO_WRITE_CLIENT } from './keto.constants.js';
|
|
9
|
+
import { KETO_READ_CLIENT } from './keto.constants.js';
|
|
10
|
+
import { KETO_MODULE_CONFIGURATION } from './keto.constants.js';
|
|
11
|
+
export const createKetoConfigurationProvider = (options) => [
|
|
12
|
+
{
|
|
13
|
+
provide: KETO_MODULE_CONFIGURATION,
|
|
14
|
+
useFactory: () => new KetoConfigurationService(options),
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
export const createKetoExportsProvider = () => [
|
|
18
|
+
{
|
|
19
|
+
provide: KETO_PERMISSIONS,
|
|
20
|
+
useFactory: (options) => new KetoPermissionsService(options),
|
|
21
|
+
inject: [KETO_MODULE_CONFIGURATION],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
provide: KETO_RELATIONS,
|
|
25
|
+
useFactory: (options) => new KetoRelationsService(options),
|
|
26
|
+
inject: [KETO_MODULE_CONFIGURATION],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
provide: KETO_READ_CLIENT,
|
|
30
|
+
useFactory: (permissionsService) => new KetoReadClientService(permissionsService),
|
|
31
|
+
inject: [KETO_PERMISSIONS],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
provide: KETO_WRITE_CLIENT,
|
|
35
|
+
useFactory: (relationshipsService) => new KetoWriteClientService(relationshipsService),
|
|
36
|
+
inject: [KETO_RELATIONS],
|
|
37
|
+
},
|
|
38
|
+
];
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './keto-read-client.service.js';
|
|
2
|
+
export * from './keto-write-client.service.js';
|
|
3
|
+
export * from './keto-configuration.service.js';
|
|
4
|
+
export * from './keto-permissions.service.js';
|
|
5
|
+
export * from './keto-relations.service.js';
|
package/dist/services/index.js
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./resource.service"), exports);
|
|
1
|
+
export * from "./keto-read-client.service.js";
|
|
2
|
+
export * from "./keto-write-client.service.js";
|
|
3
|
+
export * from "./keto-configuration.service.js";
|
|
4
|
+
export * from "./keto-permissions.service.js";
|
|
5
|
+
export * from "./keto-relations.service.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
14
|
+
import { Injectable } from '@nestjs/common';
|
|
15
|
+
import { Configuration } from '@ory/keto-client';
|
|
16
|
+
import { KETO_MODULE_CONFIGURATION } from '../module/index.js';
|
|
17
|
+
let KetoConfigurationService = class KetoConfigurationService extends Configuration {
|
|
18
|
+
options;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super(options);
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
KetoConfigurationService = __decorate([
|
|
25
|
+
Injectable(),
|
|
26
|
+
__param(0, Inject(KETO_MODULE_CONFIGURATION)),
|
|
27
|
+
__metadata("design:paramtypes", [Object])
|
|
28
|
+
], KetoConfigurationService);
|
|
29
|
+
export { KetoConfigurationService };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PermissionApi } from '@ory/keto-client';
|
|
2
|
+
import { KetoConfigurationService } from './keto-configuration.service.js';
|
|
3
|
+
export declare class KetoPermissionsService extends PermissionApi {
|
|
4
|
+
readonly configuration: KetoConfigurationService;
|
|
5
|
+
constructor(configuration: KetoConfigurationService);
|
|
6
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
14
|
+
import { Injectable } from '@nestjs/common';
|
|
15
|
+
import { PermissionApi } from '@ory/keto-client';
|
|
16
|
+
import { KETO_MODULE_CONFIGURATION } from '../module/index.js';
|
|
17
|
+
import { KetoConfigurationService } from './keto-configuration.service.js';
|
|
18
|
+
let KetoPermissionsService = class KetoPermissionsService extends PermissionApi {
|
|
19
|
+
configuration;
|
|
20
|
+
constructor(configuration) {
|
|
21
|
+
super(configuration);
|
|
22
|
+
this.configuration = configuration;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
KetoPermissionsService = __decorate([
|
|
26
|
+
Injectable(),
|
|
27
|
+
__param(0, Inject(KETO_MODULE_CONFIGURATION)),
|
|
28
|
+
__metadata("design:paramtypes", [KetoConfigurationService])
|
|
29
|
+
], KetoPermissionsService);
|
|
30
|
+
export { KetoPermissionsService };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RelationShipTuple } from '../module/index.js';
|
|
2
|
+
import { KetoPermissionsService } from './keto-permissions.service.js';
|
|
3
|
+
export declare class KetoReadClientService {
|
|
4
|
+
private readonly permissionService;
|
|
5
|
+
constructor(permissionService: KetoPermissionsService);
|
|
6
|
+
validateRelationTuple(request: RelationShipTuple): Promise<boolean>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
14
|
+
import { Injectable } from '@nestjs/common';
|
|
15
|
+
import { KetoGeneralException } from '../exceptions/index.js';
|
|
16
|
+
import { KETO_PERMISSIONS } from '../module/index.js';
|
|
17
|
+
import { KetoPermissionsService } from './keto-permissions.service.js';
|
|
18
|
+
let KetoReadClientService = class KetoReadClientService {
|
|
19
|
+
permissionService;
|
|
20
|
+
constructor(permissionService) {
|
|
21
|
+
this.permissionService = permissionService;
|
|
22
|
+
}
|
|
23
|
+
async validateRelationTuple(request) {
|
|
24
|
+
try {
|
|
25
|
+
let data;
|
|
26
|
+
if (request.subject_id !== undefined) {
|
|
27
|
+
const req = request;
|
|
28
|
+
data = {
|
|
29
|
+
relation: req.relation,
|
|
30
|
+
object: req.object,
|
|
31
|
+
namespace: req.namespace,
|
|
32
|
+
subjectId: req.subject_id,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const req = request;
|
|
37
|
+
data = {
|
|
38
|
+
relation: req.relation,
|
|
39
|
+
object: req.object,
|
|
40
|
+
namespace: req.namespace,
|
|
41
|
+
subjectSetNamespace: req.subject_set.namespace,
|
|
42
|
+
subjectSetObject: req.subject_set.object,
|
|
43
|
+
subjectSetRelation: req.subject_set.relation,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const response = await this.permissionService.checkPermissionOrError(data);
|
|
47
|
+
return response.data.allowed;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new KetoGeneralException(error.toString());
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
KetoReadClientService = __decorate([
|
|
55
|
+
Injectable(),
|
|
56
|
+
__param(0, Inject(KETO_PERMISSIONS)),
|
|
57
|
+
__metadata("design:paramtypes", [KetoPermissionsService])
|
|
58
|
+
], KetoReadClientService);
|
|
59
|
+
export { KetoReadClientService };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
14
|
+
import { Injectable } from '@nestjs/common';
|
|
15
|
+
import { RelationshipApi } from '@ory/keto-client';
|
|
16
|
+
import { Configuration } from '@ory/keto-client';
|
|
17
|
+
import { KETO_MODULE_CONFIGURATION } from '../module/index.js';
|
|
18
|
+
let KetoRelationsService = class KetoRelationsService extends RelationshipApi {
|
|
19
|
+
options;
|
|
20
|
+
constructor(options) {
|
|
21
|
+
super(options);
|
|
22
|
+
this.options = options;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
KetoRelationsService = __decorate([
|
|
26
|
+
Injectable(),
|
|
27
|
+
__param(0, Inject(KETO_MODULE_CONFIGURATION)),
|
|
28
|
+
__metadata("design:paramtypes", [Configuration])
|
|
29
|
+
], KetoRelationsService);
|
|
30
|
+
export { KetoRelationsService };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RelationshipPatchActionEnum } from '@ory/keto-client';
|
|
2
|
+
import { Relationship } from '@ory/keto-client';
|
|
3
|
+
import { RelationShipTuple } from '../module/index.js';
|
|
4
|
+
import { KetoRelationsService } from './keto-relations.service.js';
|
|
5
|
+
export declare class KetoWriteClientService {
|
|
6
|
+
private readonly relationsService;
|
|
7
|
+
constructor(relationsService: KetoRelationsService);
|
|
8
|
+
addRelationTuple(tuple: RelationShipTuple): Promise<Relationship>;
|
|
9
|
+
removeRelationTuple(tuple: RelationShipTuple): Promise<boolean>;
|
|
10
|
+
patchRelationTuple(tuple: RelationShipTuple, action: RelationshipPatchActionEnum): Promise<boolean>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
14
|
+
import { Injectable } from '@nestjs/common';
|
|
15
|
+
import { KetoGeneralException } from '../exceptions/index.js';
|
|
16
|
+
import { KETO_RELATIONS } from '../module/index.js';
|
|
17
|
+
import { KetoRelationsService } from './keto-relations.service.js';
|
|
18
|
+
let KetoWriteClientService = class KetoWriteClientService {
|
|
19
|
+
relationsService;
|
|
20
|
+
constructor(relationsService) {
|
|
21
|
+
this.relationsService = relationsService;
|
|
22
|
+
}
|
|
23
|
+
async addRelationTuple(tuple) {
|
|
24
|
+
try {
|
|
25
|
+
const data = {
|
|
26
|
+
createRelationshipBody: tuple,
|
|
27
|
+
};
|
|
28
|
+
const response = await this.relationsService.createRelationship(data);
|
|
29
|
+
return response.data;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
throw new KetoGeneralException(error.toString());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async removeRelationTuple(tuple) {
|
|
36
|
+
try {
|
|
37
|
+
const data = tuple;
|
|
38
|
+
await this.relationsService.deleteRelationships(data);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new KetoGeneralException(error.toString());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async patchRelationTuple(tuple, action) {
|
|
46
|
+
try {
|
|
47
|
+
const data = {
|
|
48
|
+
relationshipPatch: [
|
|
49
|
+
{
|
|
50
|
+
action,
|
|
51
|
+
relation_tuple: tuple,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
await this.relationsService.patchRelationships(data);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new KetoGeneralException(error.toString());
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
KetoWriteClientService = __decorate([
|
|
64
|
+
Injectable(),
|
|
65
|
+
__param(0, Inject(KETO_RELATIONS)),
|
|
66
|
+
__metadata("design:paramtypes", [KetoRelationsService])
|
|
67
|
+
], KetoWriteClientService);
|
|
68
|
+
export { KetoWriteClientService };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './relation-tuple-converter.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./relation-tuple-converter.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RelationShipTuple } from '../module/index.js';
|
|
2
|
+
type Tuple = string | ((...args: string[]) => string);
|
|
3
|
+
export declare class RelationTupleConverter {
|
|
4
|
+
private readonly tuple;
|
|
5
|
+
private readonly replacement;
|
|
6
|
+
private tupleString;
|
|
7
|
+
private result;
|
|
8
|
+
constructor(tuple: Tuple, replacement?: string);
|
|
9
|
+
private get subjectId();
|
|
10
|
+
run(): RelationShipTuple;
|
|
11
|
+
private convertToString;
|
|
12
|
+
private isTupleCorrect;
|
|
13
|
+
private getNamespace;
|
|
14
|
+
private getObject;
|
|
15
|
+
private getRelation;
|
|
16
|
+
private getSubjectSet;
|
|
17
|
+
private isSubjectSet;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { KetoRelationTupleInvalidException } from '../exceptions/index.js';
|
|
2
|
+
export class RelationTupleConverter {
|
|
3
|
+
tuple;
|
|
4
|
+
replacement;
|
|
5
|
+
tupleString;
|
|
6
|
+
result;
|
|
7
|
+
constructor(tuple, replacement = '') {
|
|
8
|
+
this.tuple = tuple;
|
|
9
|
+
this.replacement = replacement;
|
|
10
|
+
this.convertToString();
|
|
11
|
+
}
|
|
12
|
+
get subjectId() {
|
|
13
|
+
return this.tupleString;
|
|
14
|
+
}
|
|
15
|
+
run() {
|
|
16
|
+
if (!this.isTupleCorrect()) {
|
|
17
|
+
throw new KetoRelationTupleInvalidException();
|
|
18
|
+
}
|
|
19
|
+
const namespace = this.getNamespace();
|
|
20
|
+
const object = this.getObject();
|
|
21
|
+
const relation = this.getRelation();
|
|
22
|
+
if (this.isSubjectSet()) {
|
|
23
|
+
const subjectSet = this.getSubjectSet();
|
|
24
|
+
this.result = this.result;
|
|
25
|
+
this.result = {
|
|
26
|
+
namespace,
|
|
27
|
+
object,
|
|
28
|
+
relation,
|
|
29
|
+
subject_set: subjectSet,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const { subjectId } = this;
|
|
34
|
+
this.result = this.result;
|
|
35
|
+
this.result = {
|
|
36
|
+
namespace,
|
|
37
|
+
object,
|
|
38
|
+
relation,
|
|
39
|
+
subject_id: subjectId,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return this.result;
|
|
43
|
+
}
|
|
44
|
+
convertToString() {
|
|
45
|
+
if (typeof this.tuple === 'string') {
|
|
46
|
+
this.tupleString = this.tuple;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.tupleString = this.tuple(this.replacement);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
isTupleCorrect() {
|
|
53
|
+
const regex = /^\w+:\w+#\w+@[\w\W]+/i;
|
|
54
|
+
return regex.test(this.tupleString);
|
|
55
|
+
}
|
|
56
|
+
getNamespace() {
|
|
57
|
+
const endOfNamespace = this.tupleString.indexOf(':');
|
|
58
|
+
const namespace = this.tupleString.substring(0, endOfNamespace);
|
|
59
|
+
this.tupleString = this.tupleString.slice(endOfNamespace + 1);
|
|
60
|
+
return namespace;
|
|
61
|
+
}
|
|
62
|
+
getObject() {
|
|
63
|
+
const endOfObject = this.tupleString.indexOf('#');
|
|
64
|
+
const object = this.tupleString.substring(0, endOfObject);
|
|
65
|
+
this.tupleString = this.tupleString.slice(endOfObject + 1);
|
|
66
|
+
return object;
|
|
67
|
+
}
|
|
68
|
+
getRelation() {
|
|
69
|
+
const endOfRelation = this.tupleString.indexOf('@');
|
|
70
|
+
const relation = this.tupleString.substring(0, endOfRelation > 0 ? endOfRelation : undefined);
|
|
71
|
+
this.tupleString = this.tupleString.slice(endOfRelation + 1);
|
|
72
|
+
return relation;
|
|
73
|
+
}
|
|
74
|
+
getSubjectSet() {
|
|
75
|
+
const namespace = this.getNamespace();
|
|
76
|
+
const object = this.getObject();
|
|
77
|
+
const relation = this.getRelation();
|
|
78
|
+
const subjectSet = {
|
|
79
|
+
namespace,
|
|
80
|
+
object,
|
|
81
|
+
relation,
|
|
82
|
+
};
|
|
83
|
+
return subjectSet;
|
|
84
|
+
}
|
|
85
|
+
isSubjectSet() {
|
|
86
|
+
return this.tupleString.includes(':') || this.tupleString.includes('#');
|
|
87
|
+
}
|
|
88
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atls/nestjs-keto",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"license": "BSD-3-Clause",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./package.json": "./package.json",
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
5
14
|
"main": "dist/index.js",
|
|
6
15
|
"files": [
|
|
7
16
|
"dist"
|
|
@@ -12,29 +21,45 @@
|
|
|
12
21
|
"postpack": "rm -rf dist"
|
|
13
22
|
},
|
|
14
23
|
"dependencies": {
|
|
15
|
-
"@
|
|
24
|
+
"@ory/keto-client": "0.11.0-alpha.0"
|
|
16
25
|
},
|
|
17
26
|
"devDependencies": {
|
|
18
|
-
"@
|
|
19
|
-
"@nestjs/
|
|
20
|
-
"@nestjs/
|
|
21
|
-
"@
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
27
|
+
"@jest/globals": "29.7.0",
|
|
28
|
+
"@nestjs/common": "10.4.1",
|
|
29
|
+
"@nestjs/core": "10.4.1",
|
|
30
|
+
"@nestjs/graphql": "12.2.0",
|
|
31
|
+
"@nestjs/testing": "10.4.1",
|
|
32
|
+
"@types/node": "22.5.5",
|
|
33
|
+
"@types/supertest": "6.0.2",
|
|
34
|
+
"apollo-server-core": "3.3.0",
|
|
35
|
+
"get-port": "7.1.0",
|
|
36
|
+
"graphql": "16.9.0",
|
|
37
|
+
"reflect-metadata": "0.2.2",
|
|
25
38
|
"rimraf": "3.0.2",
|
|
26
|
-
"rxjs": "
|
|
27
|
-
"
|
|
39
|
+
"rxjs": "7.8.1",
|
|
40
|
+
"supertest": "6.3.4",
|
|
41
|
+
"testcontainers": "10.13.1",
|
|
42
|
+
"ts-morph": "21.0.1",
|
|
43
|
+
"typescript": "5.4.2"
|
|
28
44
|
},
|
|
29
45
|
"peerDependencies": {
|
|
30
|
-
"@nestjs/common": "
|
|
31
|
-
"@nestjs/core": "
|
|
32
|
-
"reflect-metadata": "
|
|
33
|
-
"rxjs": "
|
|
46
|
+
"@nestjs/common": "10",
|
|
47
|
+
"@nestjs/core": "10",
|
|
48
|
+
"reflect-metadata": "0.2",
|
|
49
|
+
"rxjs": "7"
|
|
34
50
|
},
|
|
35
51
|
"publishConfig": {
|
|
52
|
+
"exports": {
|
|
53
|
+
"./package.json": "./package.json",
|
|
54
|
+
".": {
|
|
55
|
+
"import": "./dist/index.js",
|
|
56
|
+
"types": "./dist/index.d.ts",
|
|
57
|
+
"default": "./dist/index.js"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
36
60
|
"main": "dist/index.js",
|
|
37
61
|
"typings": "dist/index.d.ts"
|
|
38
62
|
},
|
|
63
|
+
"typecheckSkipLibCheck": true,
|
|
39
64
|
"typings": "dist/index.d.ts"
|
|
40
65
|
}
|
package/dist/constants.d.ts
DELETED
package/dist/constants.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const AccessPolicy: (flavor: string, resource: string, action: string) => import("@nestjs/common").CustomDecorator<string>;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AccessPolicy = void 0;
|
|
4
|
-
const common_1 = require("@nestjs/common");
|
|
5
|
-
const constants_1 = require("../constants");
|
|
6
|
-
const AccessPolicy = (flavor, resource, action) => (0, common_1.SetMetadata)(constants_1.ACCESS_POLICY_METADATA, { flavor, resource, action });
|
|
7
|
-
exports.AccessPolicy = AccessPolicy;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { CanActivate } from '@nestjs/common';
|
|
2
|
-
import { ExecutionContext } from '@nestjs/common';
|
|
3
|
-
import { Reflector } from '@nestjs/core';
|
|
4
|
-
import { EnginesApi } from '@oryd/keto-client';
|
|
5
|
-
import { ResourceService } from '../services';
|
|
6
|
-
export declare class KetoAccessControlGuard implements CanActivate {
|
|
7
|
-
private reflector;
|
|
8
|
-
private keto;
|
|
9
|
-
private resourceService;
|
|
10
|
-
constructor(reflector: Reflector, keto: EnginesApi, resourceService: ResourceService);
|
|
11
|
-
getSubject(context: ExecutionContext): any;
|
|
12
|
-
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
13
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.KetoAccessControlGuard = void 0;
|
|
13
|
-
const common_1 = require("@nestjs/common");
|
|
14
|
-
const core_1 = require("@nestjs/core");
|
|
15
|
-
const graphql_1 = require("@nestjs/graphql");
|
|
16
|
-
const keto_client_1 = require("@oryd/keto-client");
|
|
17
|
-
const constants_1 = require("../constants");
|
|
18
|
-
const services_1 = require("../services");
|
|
19
|
-
let KetoAccessControlGuard = class KetoAccessControlGuard {
|
|
20
|
-
constructor(reflector, keto, resourceService) {
|
|
21
|
-
this.reflector = reflector;
|
|
22
|
-
this.keto = keto;
|
|
23
|
-
this.resourceService = resourceService;
|
|
24
|
-
}
|
|
25
|
-
getSubject(context) {
|
|
26
|
-
if (context.getType() === 'graphql') {
|
|
27
|
-
const gqlContext = graphql_1.GqlExecutionContext.create(context);
|
|
28
|
-
return gqlContext.getContext().user;
|
|
29
|
-
}
|
|
30
|
-
return context.switchToHttp().getRequest().get('x-user');
|
|
31
|
-
}
|
|
32
|
-
async canActivate(context) {
|
|
33
|
-
const subject = this.getSubject(context);
|
|
34
|
-
const policy = this.reflector.get(constants_1.ACCESS_POLICY_METADATA, context.getHandler());
|
|
35
|
-
if (!policy) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
if (!subject) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
const { body } = await this.keto.doOryAccessControlPoliciesAllow(policy.flavor, {
|
|
43
|
-
subject,
|
|
44
|
-
resource: this.resourceService.withScope(policy.resource),
|
|
45
|
-
action: policy.action,
|
|
46
|
-
context: {},
|
|
47
|
-
});
|
|
48
|
-
return body.allowed;
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
KetoAccessControlGuard = __decorate([
|
|
56
|
-
(0, common_1.Injectable)(),
|
|
57
|
-
__metadata("design:paramtypes", [core_1.Reflector,
|
|
58
|
-
keto_client_1.EnginesApi,
|
|
59
|
-
services_1.ResourceService])
|
|
60
|
-
], KetoAccessControlGuard);
|
|
61
|
-
exports.KetoAccessControlGuard = KetoAccessControlGuard;
|
package/dist/keto.module.d.ts
DELETED
package/dist/keto.module.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var KetoModule_1;
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.KetoModule = void 0;
|
|
11
|
-
const common_1 = require("@nestjs/common");
|
|
12
|
-
const keto_client_1 = require("@oryd/keto-client");
|
|
13
|
-
const constants_1 = require("./constants");
|
|
14
|
-
const services_1 = require("./services");
|
|
15
|
-
let KetoModule = KetoModule_1 = class KetoModule {
|
|
16
|
-
static forRoot(options = {}) {
|
|
17
|
-
const enginesApiProvider = {
|
|
18
|
-
provide: keto_client_1.EnginesApi,
|
|
19
|
-
useFactory: () => new keto_client_1.EnginesApi((options.url || process.env.KETO_ENGINES_URL || '').replace(/\/+$/, '')),
|
|
20
|
-
};
|
|
21
|
-
const resourcesScopeProvider = {
|
|
22
|
-
provide: constants_1.RESOURCES_SCOPE,
|
|
23
|
-
useValue: options.scope,
|
|
24
|
-
};
|
|
25
|
-
const resourceServiceProvider = {
|
|
26
|
-
provide: services_1.ResourceService,
|
|
27
|
-
useClass: services_1.ResourceService,
|
|
28
|
-
};
|
|
29
|
-
return {
|
|
30
|
-
module: KetoModule_1,
|
|
31
|
-
providers: [enginesApiProvider, resourceServiceProvider, resourcesScopeProvider],
|
|
32
|
-
exports: [enginesApiProvider, resourceServiceProvider],
|
|
33
|
-
global: true,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
KetoModule = KetoModule_1 = __decorate([
|
|
38
|
-
(0, common_1.Module)({})
|
|
39
|
-
], KetoModule);
|
|
40
|
-
exports.KetoModule = KetoModule;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.ResourceService = void 0;
|
|
16
|
-
const common_1 = require("@nestjs/common");
|
|
17
|
-
const common_2 = require("@nestjs/common");
|
|
18
|
-
const constants_1 = require("../constants");
|
|
19
|
-
const SEPARATOR = ':';
|
|
20
|
-
let ResourceService = class ResourceService {
|
|
21
|
-
constructor(scope) {
|
|
22
|
-
this.scope = scope;
|
|
23
|
-
}
|
|
24
|
-
withScope(resource) {
|
|
25
|
-
if (!resource) {
|
|
26
|
-
return resource;
|
|
27
|
-
}
|
|
28
|
-
if (!this.scope) {
|
|
29
|
-
return resource;
|
|
30
|
-
}
|
|
31
|
-
return [this.scope, resource].join(SEPARATOR);
|
|
32
|
-
}
|
|
33
|
-
withoutScope(resource) {
|
|
34
|
-
if (!resource) {
|
|
35
|
-
return resource;
|
|
36
|
-
}
|
|
37
|
-
if (!this.scope) {
|
|
38
|
-
return resource;
|
|
39
|
-
}
|
|
40
|
-
if (resource.includes(this.scope)) {
|
|
41
|
-
return resource.replace(this.scope, '').split(SEPARATOR).pop();
|
|
42
|
-
}
|
|
43
|
-
return resource;
|
|
44
|
-
}
|
|
45
|
-
isMatchScope(resource) {
|
|
46
|
-
return resource.startsWith(this.scope);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
ResourceService = __decorate([
|
|
50
|
-
(0, common_2.Injectable)(),
|
|
51
|
-
__param(0, (0, common_1.Inject)(constants_1.RESOURCES_SCOPE)),
|
|
52
|
-
__metadata("design:paramtypes", [String])
|
|
53
|
-
], ResourceService);
|
|
54
|
-
exports.ResourceService = ResourceService;
|