@discovercloudai/shared 1.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.
Files changed (69) hide show
  1. package/dist/context/access-context.d.ts +7 -0
  2. package/dist/context/access-context.js +2 -0
  3. package/dist/context/index.d.ts +1 -0
  4. package/dist/context/index.js +17 -0
  5. package/dist/dto/account.dto.d.ts +9 -0
  6. package/dist/dto/account.dto.js +2 -0
  7. package/dist/dto/auth-service.dtos.d.ts +51 -0
  8. package/dist/dto/auth-service.dtos.js +2 -0
  9. package/dist/dto/index.d.ts +3 -0
  10. package/dist/dto/index.js +19 -0
  11. package/dist/dto/membership.dto.d.ts +11 -0
  12. package/dist/dto/membership.dto.js +2 -0
  13. package/dist/dto/organization.dto.d.ts +10 -0
  14. package/dist/dto/organization.dto.js +2 -0
  15. package/dist/dto/response.dto.d.ts +54 -0
  16. package/dist/dto/response.dto.js +2 -0
  17. package/dist/dto/response.dtos.d.ts +48 -0
  18. package/dist/dto/response.dtos.js +2 -0
  19. package/dist/dto/user-service.dtos.d.ts +54 -0
  20. package/dist/dto/user-service.dtos.js +2 -0
  21. package/dist/dto/user.dto.d.ts +10 -0
  22. package/dist/dto/user.dto.js +2 -0
  23. package/dist/enums/account-status.enum.d.ts +5 -0
  24. package/dist/enums/account-status.enum.js +9 -0
  25. package/dist/enums/auth-service.enums.d.ts +12 -0
  26. package/dist/enums/auth-service.enums.js +17 -0
  27. package/dist/enums/index.d.ts +3 -0
  28. package/dist/enums/index.js +19 -0
  29. package/dist/enums/membership-status.enum.d.ts +5 -0
  30. package/dist/enums/membership-status.enum.js +9 -0
  31. package/dist/enums/organization-role.enum.d.ts +6 -0
  32. package/dist/enums/organization-role.enum.js +10 -0
  33. package/dist/enums/organization-status.enum.d.ts +5 -0
  34. package/dist/enums/organization-status.enum.js +9 -0
  35. package/dist/enums/permissions.types.d.ts +12 -0
  36. package/dist/enums/permissions.types.js +17 -0
  37. package/dist/enums/user-role.enum.d.ts +7 -0
  38. package/dist/enums/user-role.enum.js +11 -0
  39. package/dist/enums/user-service.enums.d.ts +32 -0
  40. package/dist/enums/user-service.enums.js +41 -0
  41. package/dist/enums/user-status.enum.d.ts +5 -0
  42. package/dist/enums/user-status.enum.js +9 -0
  43. package/dist/errors/app-error.d.ts +6 -0
  44. package/dist/errors/app-error.js +19 -0
  45. package/dist/errors/http-errors.d.ts +22 -0
  46. package/dist/errors/http-errors.js +46 -0
  47. package/dist/errors/index.d.ts +2 -0
  48. package/dist/errors/index.js +18 -0
  49. package/dist/index.d.ts +5 -0
  50. package/dist/index.js +21 -0
  51. package/dist/internal/internal-jwt.service.d.ts +13 -0
  52. package/dist/internal/internal-jwt.service.js +88 -0
  53. package/dist/internal/internal-jwt.types.d.ts +7 -0
  54. package/dist/internal/internal-jwt.types.js +2 -0
  55. package/dist/internal/internal-key-manager.d.ts +16 -0
  56. package/dist/internal/internal-key-manager.js +67 -0
  57. package/dist/internal/registry.d.ts +8 -0
  58. package/dist/internal/registry.js +34 -0
  59. package/dist/internal/service-client.d.ts +9 -0
  60. package/dist/internal/service-client.js +94 -0
  61. package/dist/permissions/global-permissions.d.ts +3 -0
  62. package/dist/permissions/global-permissions.js +30 -0
  63. package/dist/permissions/index.d.ts +3 -0
  64. package/dist/permissions/index.js +19 -0
  65. package/dist/permissions/is-allowed.d.ts +3 -0
  66. package/dist/permissions/is-allowed.js +16 -0
  67. package/dist/permissions/org-permissions.d.ts +3 -0
  68. package/dist/permissions/org-permissions.js +19 -0
  69. package/package.json +28 -0
@@ -0,0 +1,22 @@
1
+ import { AppError } from "./app-error";
2
+ export declare class BadRequestError extends AppError {
3
+ constructor(message?: string, details?: unknown);
4
+ }
5
+ export declare class UnauthorizedError extends AppError {
6
+ constructor(message?: string, details?: unknown);
7
+ }
8
+ export declare class ForbiddenError extends AppError {
9
+ constructor(message?: string, details?: unknown);
10
+ }
11
+ export declare class NotFoundError extends AppError {
12
+ constructor(message?: string, details?: unknown);
13
+ }
14
+ export declare class ConflictError extends AppError {
15
+ constructor(message?: string, details?: unknown);
16
+ }
17
+ export declare class UnprocessableEntityError extends AppError {
18
+ constructor(message?: string, details?: unknown);
19
+ }
20
+ export declare class InternalServerError extends AppError {
21
+ constructor(message?: string, details?: unknown);
22
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InternalServerError = exports.UnprocessableEntityError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = void 0;
4
+ const app_error_1 = require("./app-error");
5
+ class BadRequestError extends app_error_1.AppError {
6
+ constructor(message = "Bad Request", details) {
7
+ super("BAD_REQUEST", 400, message, details);
8
+ }
9
+ }
10
+ exports.BadRequestError = BadRequestError;
11
+ class UnauthorizedError extends app_error_1.AppError {
12
+ constructor(message = "Unauthorized", details) {
13
+ super("UNAUTHORIZED", 401, message, details);
14
+ }
15
+ }
16
+ exports.UnauthorizedError = UnauthorizedError;
17
+ class ForbiddenError extends app_error_1.AppError {
18
+ constructor(message = "Forbidden", details) {
19
+ super("FORBIDDEN", 403, message, details);
20
+ }
21
+ }
22
+ exports.ForbiddenError = ForbiddenError;
23
+ class NotFoundError extends app_error_1.AppError {
24
+ constructor(message = "Not Found", details) {
25
+ super("NOT_FOUND", 404, message, details);
26
+ }
27
+ }
28
+ exports.NotFoundError = NotFoundError;
29
+ class ConflictError extends app_error_1.AppError {
30
+ constructor(message = "Conflict", details) {
31
+ super("CONFLICT", 409, message, details);
32
+ }
33
+ }
34
+ exports.ConflictError = ConflictError;
35
+ class UnprocessableEntityError extends app_error_1.AppError {
36
+ constructor(message = "Unprocessable Entity", details) {
37
+ super("UNPROCESSABLE_ENTITY", 422, message, details);
38
+ }
39
+ }
40
+ exports.UnprocessableEntityError = UnprocessableEntityError;
41
+ class InternalServerError extends app_error_1.AppError {
42
+ constructor(message = "Internal Server Error", details) {
43
+ super("INTERNAL_SERVER_ERROR", 500, message, details);
44
+ }
45
+ }
46
+ exports.InternalServerError = InternalServerError;
@@ -0,0 +1,2 @@
1
+ export * from "./app-error";
2
+ export * from "./http-errors";
@@ -0,0 +1,18 @@
1
+ "use strict";
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("./app-error"), exports);
18
+ __exportStar(require("./http-errors"), exports);
@@ -0,0 +1,5 @@
1
+ export * from "./permissions";
2
+ export * from "./context";
3
+ export * from "./dto";
4
+ export * from "./enums";
5
+ export * from "./errors";
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
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("./permissions"), exports);
18
+ __exportStar(require("./context"), exports);
19
+ __exportStar(require("./dto"), exports);
20
+ __exportStar(require("./enums"), exports);
21
+ __exportStar(require("./errors"), exports);
@@ -0,0 +1,13 @@
1
+ import { InternalKeyManager } from "./internal-key-manager";
2
+ import { InternalJwtPayload } from "./internal-jwt.types";
3
+ export declare class InternalJwtService {
4
+ private readonly keyManager;
5
+ private readonly serviceName;
6
+ private jwksCache;
7
+ constructor(keyManager: InternalKeyManager);
8
+ sign(payload: {
9
+ requestId: string;
10
+ }, targetService: string): Promise<string>;
11
+ verify(token: string): Promise<InternalJwtPayload>;
12
+ private getRemoteJWKS;
13
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.InternalJwtService = void 0;
37
+ const jose = __importStar(require("jose"));
38
+ class InternalJwtService {
39
+ constructor(keyManager) {
40
+ this.keyManager = keyManager;
41
+ this.jwksCache = new Map();
42
+ this.serviceName = process.env.SERVICE_NAME || "unknown-service";
43
+ }
44
+ async sign(payload, targetService) {
45
+ const signer = this.keyManager.getPrivateKey();
46
+ const kid = this.keyManager.getKid();
47
+ return new jose.SignJWT({
48
+ ...payload,
49
+ typ: "internal"
50
+ })
51
+ .setProtectedHeader({ alg: "RS256", kid })
52
+ .setIssuer(this.serviceName)
53
+ .setAudience(targetService)
54
+ .setIssuedAt()
55
+ .setExpirationTime("1m")
56
+ .sign(signer);
57
+ }
58
+ async verify(token) {
59
+ const unverified = jose.decodeJwt(token);
60
+ if (!unverified.iss)
61
+ throw new Error("Missing issuer");
62
+ if (unverified.typ !== "internal")
63
+ throw new Error("Invalid token type");
64
+ const jwks = this.getRemoteJWKS(unverified.iss);
65
+ const { payload } = await jose.jwtVerify(token, jwks, {
66
+ algorithms: ["RS256"],
67
+ audience: this.serviceName,
68
+ issuer: unverified.iss
69
+ });
70
+ return payload;
71
+ }
72
+ getRemoteJWKS(issuer) {
73
+ const envKey = `${issuer.replace(/-/g, "_").toUpperCase()}_URL`;
74
+ const baseUrl = process.env[envKey];
75
+ const url = baseUrl
76
+ ? `${baseUrl}/internal/jwks`
77
+ : `http://${issuer}/internal/jwks`;
78
+ if (!this.jwksCache.has(url)) {
79
+ console.log(`[InternalJwt] Caching JWKS for ${issuer} at ${url}`);
80
+ this.jwksCache.set(url, jose.createRemoteJWKSet(new URL(url), {
81
+ cacheMaxAge: 600000,
82
+ cooldownDuration: 30000
83
+ }));
84
+ }
85
+ return this.jwksCache.get(url);
86
+ }
87
+ }
88
+ exports.InternalJwtService = InternalJwtService;
@@ -0,0 +1,7 @@
1
+ import { JWTPayload } from "jose";
2
+ export interface InternalJwtPayload extends JWTPayload {
3
+ iss: string;
4
+ aud: string;
5
+ typ: "internal";
6
+ requestId: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,16 @@
1
+ import { JWK } from "jose";
2
+ import { KeyObject } from "crypto";
3
+ export declare class InternalKeyManager {
4
+ private privateKey;
5
+ private publicKey;
6
+ private jwks;
7
+ private readonly serviceName;
8
+ private readonly keyPath;
9
+ constructor();
10
+ private init;
11
+ getPrivateKey(): KeyObject | CryptoKey;
12
+ getPublicJwks(): {
13
+ keys: JWK[];
14
+ };
15
+ getKid(): string;
16
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InternalKeyManager = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const jose_1 = require("jose");
10
+ class InternalKeyManager {
11
+ constructor() {
12
+ this.jwks = [];
13
+ this.serviceName = process.env.SERVICE_NAME || "unknown-service";
14
+ this.keyPath = (() => {
15
+ const envPath = process.env.INTERNAL_KEYS_PATH;
16
+ if (!envPath) {
17
+ console.warn("[InternalKeyManager] INTERNAL_KEYS_PATH not set. Using default: src/keys/internal");
18
+ return path_1.default.join(process.cwd(), "src/keys/internal");
19
+ }
20
+ return path_1.default.isAbsolute(envPath) ? envPath : path_1.default.join(process.cwd(), envPath);
21
+ })();
22
+ this.init();
23
+ }
24
+ async init() {
25
+ try {
26
+ if (!fs_1.default.existsSync(this.keyPath)) {
27
+ console.error(`[InternalKeyManager] Missing keys directory: ${this.keyPath}`);
28
+ return;
29
+ }
30
+ const privPath = path_1.default.join(this.keyPath, "/private/private.pem");
31
+ if (fs_1.default.existsSync(privPath)) {
32
+ const privPem = fs_1.default.readFileSync(privPath, "utf8");
33
+ this.privateKey = await (0, jose_1.importPKCS8)(privPem, "RS256");
34
+ }
35
+ const pubPath = path_1.default.join(this.keyPath, "/public/public.pem");
36
+ if (fs_1.default.existsSync(pubPath)) {
37
+ const pubPem = fs_1.default.readFileSync(pubPath, "utf8");
38
+ this.publicKey = await (0, jose_1.importSPKI)(pubPem, "RS256");
39
+ const jwk = await (0, jose_1.exportJWK)(this.publicKey);
40
+ this.jwks = [{
41
+ ...jwk,
42
+ kid: `${this.serviceName}-internal`,
43
+ use: "sig",
44
+ alg: "RS256"
45
+ }];
46
+ }
47
+ console.log(`[InternalKeyManager] Loaded keys for: ${this.serviceName}`);
48
+ }
49
+ catch (error) {
50
+ console.error("[InternalKeyManager] Failed to load keys.", error);
51
+ if (process.env.NODE_ENV === "production")
52
+ process.exit(1);
53
+ }
54
+ }
55
+ getPrivateKey() {
56
+ if (!this.privateKey)
57
+ throw new Error("Private key not loaded");
58
+ return this.privateKey;
59
+ }
60
+ getPublicJwks() {
61
+ return { keys: this.jwks };
62
+ }
63
+ getKid() {
64
+ return `${this.serviceName}-internal`;
65
+ }
66
+ }
67
+ exports.InternalKeyManager = InternalKeyManager;
@@ -0,0 +1,8 @@
1
+ export declare const SERVICE_REGISTRY: {
2
+ readonly auth: "auth-service";
3
+ readonly user: "user-service";
4
+ readonly billing: "billing-service";
5
+ readonly notifications: "notification-service";
6
+ };
7
+ export type ServiceName = typeof SERVICE_REGISTRY[keyof typeof SERVICE_REGISTRY];
8
+ export declare const extractServiceName: (url?: string) => ServiceName | null;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractServiceName = exports.SERVICE_REGISTRY = void 0;
4
+ exports.SERVICE_REGISTRY = {
5
+ auth: "auth-service",
6
+ user: "user-service",
7
+ billing: "billing-service",
8
+ notifications: "notification-service"
9
+ };
10
+ const extractServiceName = (url) => {
11
+ if (!url)
12
+ return null;
13
+ try {
14
+ const u = new URL(url);
15
+ // If localhost, infer by port
16
+ switch (u.port) {
17
+ case "3001": return "auth-service";
18
+ case "3002": return "user-service";
19
+ case "3003": return "billing-service";
20
+ case "3004": return "notification-service";
21
+ default: break;
22
+ }
23
+ // Docker/K8s case: hostname is service name
24
+ const host = u.hostname.split(".")[0];
25
+ if (Object.values(exports.SERVICE_REGISTRY).includes(host)) {
26
+ return host;
27
+ }
28
+ return null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ };
34
+ exports.extractServiceName = extractServiceName;
@@ -0,0 +1,9 @@
1
+ import { AxiosInstance } from "axios";
2
+ import { InternalJwtService } from "./internal-jwt.service";
3
+ export declare class ServiceClient {
4
+ private readonly internalJwt;
5
+ readonly http: AxiosInstance;
6
+ constructor(internalJwt: InternalJwtService);
7
+ private setupRetry;
8
+ private setupInterceptors;
9
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ServiceClient = void 0;
40
+ const axios_1 = __importStar(require("axios"));
41
+ const axios_retry_1 = __importDefault(require("axios-retry"));
42
+ const registry_1 = require("./registry");
43
+ class ServiceClient {
44
+ constructor(internalJwt) {
45
+ this.internalJwt = internalJwt;
46
+ this.http = axios_1.default.create({
47
+ timeout: 8000,
48
+ validateStatus: () => true
49
+ });
50
+ this.setupRetry();
51
+ this.setupInterceptors();
52
+ }
53
+ setupRetry() {
54
+ (0, axios_retry_1.default)(this.http, {
55
+ retries: 3,
56
+ retryDelay: axios_retry_1.default.exponentialDelay,
57
+ retryCondition: (err) => {
58
+ if (axios_retry_1.default.isNetworkError(err))
59
+ return true;
60
+ return (err.response?.status ?? 0) >= 500;
61
+ }
62
+ });
63
+ }
64
+ setupInterceptors() {
65
+ this.http.interceptors.request.use(async (config) => {
66
+ if (!config.headers)
67
+ config.headers = new axios_1.AxiosHeaders();
68
+ const reqId = config.headers["x-request-id"] ||
69
+ `req_${Math.random().toString(36).slice(2)}`;
70
+ config.headers["x-request-id"] = reqId;
71
+ const fullUrl = config.url?.startsWith("http")
72
+ ? config.url
73
+ : config.baseURL;
74
+ if (!fullUrl)
75
+ throw new Error("Missing baseURL or absolute URL for internal service request");
76
+ const target = (0, registry_1.extractServiceName)(fullUrl);
77
+ if (!target)
78
+ throw new Error(`Cannot extract serviceName from ${fullUrl}`);
79
+ const token = await this.internalJwt.sign({ requestId: reqId }, target);
80
+ config.headers["x-internal-jwt"] = token;
81
+ return config;
82
+ });
83
+ this.http.interceptors.response.use((res) => {
84
+ if (res.status >= 200 && res.status < 300)
85
+ return res;
86
+ throw {
87
+ status: res.status,
88
+ message: res.data?.error?.message ?? "Service Error",
89
+ details: res.data
90
+ };
91
+ });
92
+ }
93
+ }
94
+ exports.ServiceClient = ServiceClient;
@@ -0,0 +1,3 @@
1
+ import { AccountRole, GlobalPermission } from "../enums";
2
+ export declare const globalRolePermissions: Record<AccountRole, readonly GlobalPermission[]>;
3
+ export declare const canPerformGlobalPermission: (role: AccountRole, permission: GlobalPermission) => boolean;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canPerformGlobalPermission = exports.globalRolePermissions = void 0;
4
+ const enums_1 = require("../enums");
5
+ exports.globalRolePermissions = {
6
+ [enums_1.AccountRole.SUPERADMIN]: [
7
+ enums_1.GlobalPermission.MANAGE_SYSTEM,
8
+ enums_1.GlobalPermission.MANAGE_ALL_ORGS,
9
+ enums_1.GlobalPermission.MANAGE_USERS,
10
+ enums_1.GlobalPermission.VIEW_SYSTEM_LOGS,
11
+ enums_1.GlobalPermission.SUPPORT_ACTIONS,
12
+ enums_1.GlobalPermission.MODERATE_CONTENT
13
+ ],
14
+ [enums_1.AccountRole.ADMIN]: [
15
+ enums_1.GlobalPermission.MANAGE_USERS,
16
+ enums_1.GlobalPermission.SUPPORT_ACTIONS,
17
+ enums_1.GlobalPermission.VIEW_SYSTEM_LOGS
18
+ ],
19
+ [enums_1.AccountRole.SUPPORT]: [
20
+ enums_1.GlobalPermission.SUPPORT_ACTIONS
21
+ ],
22
+ [enums_1.AccountRole.MODERATOR]: [
23
+ enums_1.GlobalPermission.MODERATE_CONTENT
24
+ ],
25
+ [enums_1.AccountRole.USER]: []
26
+ };
27
+ const canPerformGlobalPermission = (role, permission) => {
28
+ return exports.globalRolePermissions[role]?.includes(permission) ?? false;
29
+ };
30
+ exports.canPerformGlobalPermission = canPerformGlobalPermission;
@@ -0,0 +1,3 @@
1
+ export * from "./global-permissions";
2
+ export * from "./org-permissions";
3
+ export * from "./is-allowed";
@@ -0,0 +1,19 @@
1
+ "use strict";
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("./global-permissions"), exports);
18
+ __exportStar(require("./org-permissions"), exports);
19
+ __exportStar(require("./is-allowed"), exports);
@@ -0,0 +1,3 @@
1
+ import { AccessContext } from "../context";
2
+ import { GlobalPermission, OrgPermission } from "../enums";
3
+ export declare const isAllowed: (ctx: AccessContext, permission: GlobalPermission | OrgPermission) => boolean;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAllowed = void 0;
4
+ const enums_1 = require("../enums");
5
+ const global_permissions_1 = require("./global-permissions");
6
+ const org_permissions_1 = require("./org-permissions");
7
+ const isAllowed = (ctx, permission) => {
8
+ if (Object.values(enums_1.GlobalPermission).includes(permission)) {
9
+ // We now use the role pulled from the token context, not a user database entity
10
+ return (0, global_permissions_1.canPerformGlobalPermission)(ctx.accountRole, permission);
11
+ }
12
+ if (!ctx.membership)
13
+ return false;
14
+ return (0, org_permissions_1.canPerformOrgPermission)(ctx.membership.role, ctx.membership.status, permission);
15
+ };
16
+ exports.isAllowed = isAllowed;
@@ -0,0 +1,3 @@
1
+ import { OrganizationRole, MembershipStatus, OrgPermission } from "../enums";
2
+ export declare const orgRolePermissions: Record<OrganizationRole, readonly OrgPermission[]>;
3
+ export declare const canPerformOrgPermission: (role: OrganizationRole, status: MembershipStatus, permission: OrgPermission) => boolean;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canPerformOrgPermission = exports.orgRolePermissions = void 0;
4
+ const enums_1 = require("../enums");
5
+ exports.orgRolePermissions = {
6
+ [enums_1.OrganizationRole.OWNER]: [
7
+ enums_1.OrgPermission.MANAGE_ORG,
8
+ enums_1.OrgPermission.MANAGE_MEMBERS,
9
+ ],
10
+ [enums_1.OrganizationRole.ADMIN]: [enums_1.OrgPermission.MANAGE_MEMBERS],
11
+ [enums_1.OrganizationRole.EDITOR]: [],
12
+ [enums_1.OrganizationRole.VIEWER]: [],
13
+ };
14
+ const canPerformOrgPermission = (role, status, permission) => {
15
+ if (status !== enums_1.MembershipStatus.ACTIVE)
16
+ return false;
17
+ return exports.orgRolePermissions[role]?.includes(permission) ?? false;
18
+ };
19
+ exports.canPerformOrgPermission = canPerformOrgPermission;
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@discovercloudai/shared",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "type": "commonjs",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc -p tsconfig.json",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "dependencies": {
19
+ "axios-retry": "^4.5.0",
20
+ "crypto": "^1.0.1",
21
+ "jose": "^6.1.3",
22
+ "tsc": "^2.0.4",
23
+ "typescript": "^5.9.3"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^25.3.0"
27
+ }
28
+ }