@innvoid/getmarket-sdk 0.1.8 → 0.1.10

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.
@@ -30,6 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/middlewares/index.ts
31
31
  var middlewares_exports = {};
32
32
  __export(middlewares_exports, {
33
+ allowAuthAdminOrPerm: () => allowAuthAdminOrPerm,
34
+ allowSysAdminOrAnyPermission: () => allowSysAdminOrAnyPermission,
35
+ allowSysAdminOrPermissionsAll: () => allowSysAdminOrPermissionsAll,
36
+ allowSysAdminOrRoles: () => allowSysAdminOrRoles,
37
+ allowSysAdminOrRolesOrAnyPermission: () => allowSysAdminOrRolesOrAnyPermission,
33
38
  internalAuth: () => internalAuth,
34
39
  parseHeaders: () => parseHeaders,
35
40
  requestId: () => requestId,
@@ -291,8 +296,312 @@ function requireRolesOrAnyPermission(roles, perms, options) {
291
296
  return next();
292
297
  };
293
298
  }
299
+
300
+ // src/auth/jwt.ts
301
+ var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
302
+
303
+ // src/auth/authentication.ts
304
+ var import_firebase_admin = __toESM(require("firebase-admin"), 1);
305
+ var import_jsonwebtoken2 = __toESM(require("jsonwebtoken"), 1);
306
+ var import_fs2 = __toESM(require("fs"), 1);
307
+ function getBearerToken(req) {
308
+ const auth = String(req.headers?.authorization || "");
309
+ if (!auth.startsWith("Bearer ")) return null;
310
+ const token = auth.slice(7).trim();
311
+ return token.length ? token : null;
312
+ }
313
+ function readPublicKey() {
314
+ const publicKeyPath = process.env.JWT_PUBLIC_KEY_PATH;
315
+ const publicKeyEnv = process.env.AUTH_JWT_PUBLIC_KEY || process.env.AUTH_RSA_PUBLIC_KEY || "";
316
+ if (publicKeyPath) {
317
+ const v = import_fs2.default.readFileSync(publicKeyPath, "utf8").trim();
318
+ if (v) return v;
319
+ }
320
+ const envKey = publicKeyEnv.replace(/\\n/g, "\n").trim();
321
+ if (envKey) return envKey;
322
+ throw new Error(
323
+ "Missing RS256 public key (JWT_PUBLIC_KEY_PATH / AUTH_JWT_PUBLIC_KEY / AUTH_RSA_PUBLIC_KEY)"
324
+ );
325
+ }
326
+ function verifyBackendJwtRS2562(raw) {
327
+ const publicKey = readPublicKey();
328
+ const audience = process.env.JWT_AUDIENCE || process.env.AUTH_JWT_AUDIENCE || "getmarket.api";
329
+ const issuer = process.env.JWT_ISSUER || process.env.AUTH_JWT_ISSUER || "getmarket-auth";
330
+ return import_jsonwebtoken2.default.verify(raw, publicKey, {
331
+ algorithms: ["RS256"],
332
+ audience,
333
+ issuer
334
+ });
335
+ }
336
+ function normalizeUid(v) {
337
+ const s = String(v ?? "").trim();
338
+ return s.length ? s : null;
339
+ }
340
+ function deriveCompanyBranch(decoded, companyUid, branchUid) {
341
+ const companiesFromToken = Array.isArray(decoded?.companies) ? decoded.companies : [];
342
+ const company = decoded?.company ?? (companyUid ? companiesFromToken.find((c) => c?.uid === companyUid) : null) ?? null;
343
+ const branch = decoded?.branch ?? (branchUid && company?.branches ? (company.branches || []).find((b) => b?.uid === branchUid) : null) ?? null;
344
+ return { companiesFromToken, company, branch };
345
+ }
346
+ function createAuthMiddleware(opts) {
347
+ const { subject, allowFirebaseIdToken = false } = opts;
348
+ return async (req, res, next) => {
349
+ const token = getBearerToken(req);
350
+ if (!token) {
351
+ return res.status(401).json({
352
+ ok: false,
353
+ code: "AUTH_MISSING_TOKEN",
354
+ message: "Missing Authorization Bearer token"
355
+ });
356
+ }
357
+ try {
358
+ const decoded = verifyBackendJwtRS2562(token);
359
+ const headerCtx = req.context || {};
360
+ const companyUid = normalizeUid(headerCtx.company_uid);
361
+ const branchUid = normalizeUid(headerCtx.branch_uid);
362
+ const { companiesFromToken, company, branch } = deriveCompanyBranch(decoded, companyUid, branchUid);
363
+ const ctx = {
364
+ tokenType: "backend",
365
+ subject,
366
+ company_uid: companyUid ?? void 0,
367
+ branch_uid: branchUid ?? void 0,
368
+ companies: companiesFromToken,
369
+ company,
370
+ branch,
371
+ roles: Array.isArray(decoded?.roles) ? decoded.roles : [],
372
+ permissions: Array.isArray(decoded?.permissions) ? decoded.permissions : [],
373
+ denied_permissions: Array.isArray(decoded?.denied_permissions) ? decoded.denied_permissions : [],
374
+ session: {
375
+ jti: decoded?.jti,
376
+ device_id: decoded?.device_id,
377
+ expires_at: decoded?.exp
378
+ }
379
+ };
380
+ if (subject === "employee") {
381
+ const employee = decoded?.employee ?? decoded?.user ?? null;
382
+ if (!employee) {
383
+ return res.status(401).json({
384
+ ok: false,
385
+ code: "AUTH_EMPLOYEE_NOT_FOUND",
386
+ message: "Employee not found in token"
387
+ });
388
+ }
389
+ ctx.employee = employee;
390
+ } else {
391
+ const customer = decoded?.customer ?? null;
392
+ if (!customer) {
393
+ return res.status(401).json({
394
+ ok: false,
395
+ code: "AUTH_CUSTOMER_NOT_FOUND",
396
+ message: "Customer not found in token"
397
+ });
398
+ }
399
+ ctx.customer = customer;
400
+ }
401
+ req.auth = ctx;
402
+ return next();
403
+ } catch {
404
+ if (!allowFirebaseIdToken) {
405
+ return res.status(401).json({
406
+ ok: false,
407
+ code: "AUTH_INVALID_TOKEN",
408
+ message: "Invalid or expired token"
409
+ });
410
+ }
411
+ try {
412
+ const firebaseDecoded = await import_firebase_admin.default.auth().verifyIdToken(token);
413
+ if (firebaseDecoded.email && firebaseDecoded.email_verified === false) {
414
+ return res.status(401).json({
415
+ ok: false,
416
+ code: "AUTH_EMAIL_NOT_VERIFIED",
417
+ message: "Email not verified"
418
+ });
419
+ }
420
+ const headerCtx = req.context || {};
421
+ const companyUid = normalizeUid(headerCtx.company_uid);
422
+ const branchUid = normalizeUid(headerCtx.branch_uid);
423
+ req.auth = {
424
+ tokenType: "backend",
425
+ subject,
426
+ firebase: firebaseDecoded,
427
+ company_uid: companyUid ?? void 0,
428
+ branch_uid: branchUid ?? void 0,
429
+ companies: [],
430
+ roles: [],
431
+ permissions: [],
432
+ denied_permissions: []
433
+ };
434
+ return next();
435
+ } catch {
436
+ return res.status(401).json({
437
+ ok: false,
438
+ code: "AUTH_INVALID_TOKEN",
439
+ message: "Invalid or expired token"
440
+ });
441
+ }
442
+ }
443
+ };
444
+ }
445
+ var authEmployeeRequired = createAuthMiddleware({ subject: "employee", allowFirebaseIdToken: false });
446
+ var authCustomerRequired = createAuthMiddleware({ subject: "customer", allowFirebaseIdToken: false });
447
+ var authEmployeeAllowFirebase = createAuthMiddleware({ subject: "employee", allowFirebaseIdToken: true });
448
+ var authCustomerAllowFirebase = createAuthMiddleware({ subject: "customer", allowFirebaseIdToken: true });
449
+
450
+ // src/middlewares/guards.ts
451
+ function normalizeRole(r) {
452
+ if (!r) return null;
453
+ if (typeof r === "string") return r;
454
+ return r.code || r.name || null;
455
+ }
456
+ function normalizePerm(p) {
457
+ if (!p) return null;
458
+ if (typeof p === "string") return p;
459
+ return p.code || p.name || null;
460
+ }
461
+ function isSysAdmin2(roles) {
462
+ if (!Array.isArray(roles)) return false;
463
+ return roles.some((r) => normalizeRole(r) === "SYS_ADMIN");
464
+ }
465
+ function getAuth2(req) {
466
+ return req.auth ?? {};
467
+ }
468
+ function permissionSets(auth) {
469
+ const allow = new Set(
470
+ (auth.permissions ?? []).map(normalizePerm).filter(Boolean)
471
+ );
472
+ const deny = new Set(
473
+ (auth.denied_permissions ?? []).map(normalizePerm).filter(Boolean)
474
+ );
475
+ return { allow, deny };
476
+ }
477
+ function allowSysAdminOrAnyPermission(...perms) {
478
+ const required = (perms ?? []).filter(Boolean);
479
+ return [
480
+ parseHeaders,
481
+ authEmployeeRequired,
482
+ (req, res, next) => {
483
+ const auth = getAuth2(req);
484
+ if (isSysAdmin2(auth.roles)) return next();
485
+ const { allow, deny } = permissionSets(auth);
486
+ for (const p of required) {
487
+ if (deny.has(p)) {
488
+ return sendError(req, res, 403, "FORBIDDEN", `Denied permission: ${p}`, {
489
+ denied: p
490
+ });
491
+ }
492
+ }
493
+ const ok = required.some((p) => allow.has(p));
494
+ if (!ok) {
495
+ return sendError(req, res, 403, "FORBIDDEN", "Missing permissions (ANY)", {
496
+ required
497
+ });
498
+ }
499
+ return next();
500
+ }
501
+ ];
502
+ }
503
+ function allowSysAdminOrPermissionsAll(...perms) {
504
+ const required = (perms ?? []).filter(Boolean);
505
+ return [
506
+ parseHeaders,
507
+ authEmployeeRequired,
508
+ (req, res, next) => {
509
+ const auth = getAuth2(req);
510
+ if (isSysAdmin2(auth.roles)) return next();
511
+ const { allow, deny } = permissionSets(auth);
512
+ for (const p of required) {
513
+ if (deny.has(p)) {
514
+ return sendError(req, res, 403, "FORBIDDEN", `Denied permission: ${p}`, {
515
+ denied: p
516
+ });
517
+ }
518
+ }
519
+ const missing = required.filter((p) => !allow.has(p));
520
+ if (missing.length) {
521
+ return sendError(req, res, 403, "FORBIDDEN", "Missing permissions (ALL)", {
522
+ required,
523
+ missing
524
+ });
525
+ }
526
+ return next();
527
+ }
528
+ ];
529
+ }
530
+ function allowSysAdminOrRoles(...roles) {
531
+ const required = (roles ?? []).filter(Boolean);
532
+ return [
533
+ parseHeaders,
534
+ authEmployeeRequired,
535
+ (req, res, next) => {
536
+ const auth = getAuth2(req);
537
+ if (isSysAdmin2(auth.roles)) return next();
538
+ const have = new Set(
539
+ (auth.roles ?? []).map(normalizeRole).filter(Boolean)
540
+ );
541
+ const ok = required.some((r) => have.has(r));
542
+ if (!ok) {
543
+ return sendError(req, res, 403, "FORBIDDEN", "Role not allowed", {
544
+ required
545
+ });
546
+ }
547
+ return next();
548
+ }
549
+ ];
550
+ }
551
+
552
+ // src/middlewares/accessControl.ts
553
+ function normalizeList(v) {
554
+ return Array.isArray(v) ? v : [v];
555
+ }
556
+ function roleCode(r) {
557
+ if (!r) return null;
558
+ return typeof r === "string" ? r : r.code || r.name || null;
559
+ }
560
+ function permCode(p) {
561
+ if (!p) return null;
562
+ return typeof p === "string" ? p : p.code || p.name || null;
563
+ }
564
+ function isSysAdmin3(roles) {
565
+ if (!Array.isArray(roles)) return false;
566
+ return roles.map(roleCode).filter(Boolean).includes("SYS_ADMIN");
567
+ }
568
+ function allowSysAdminOrRolesOrAnyPermission(roles, permissions) {
569
+ const requiredRoles = normalizeList(roles).filter(Boolean);
570
+ const requiredPerms = normalizeList(permissions).filter(Boolean);
571
+ return [
572
+ parseHeaders,
573
+ authEmployeeRequired,
574
+ (req, res, next) => {
575
+ const auth = req.auth || {};
576
+ if (isSysAdmin3(auth.roles)) return next();
577
+ const deny = new Set((auth.denied_permissions || []).map(permCode).filter(Boolean));
578
+ for (const p of requiredPerms) {
579
+ if (deny.has(p)) {
580
+ return sendError(req, res, 403, "FORBIDDEN", `Denied: ${p}`, { permission: p });
581
+ }
582
+ }
583
+ const haveRoles = new Set((auth.roles || []).map(roleCode).filter(Boolean));
584
+ if (requiredRoles.some((r) => haveRoles.has(r))) return next();
585
+ const havePerms = new Set((auth.permissions || []).map(permCode).filter(Boolean));
586
+ if (requiredPerms.some((p) => havePerms.has(p))) return next();
587
+ return sendError(req, res, 403, "FORBIDDEN", "Permission denied", {
588
+ roles: requiredRoles,
589
+ permissions: requiredPerms,
590
+ mode: "ROLES_OR_ANY_PERMISSION"
591
+ });
592
+ }
593
+ ];
594
+ }
595
+ function allowAuthAdminOrPerm(permission) {
596
+ return allowSysAdminOrRolesOrAnyPermission(["AUTH_ADMIN"], [permission]);
597
+ }
294
598
  // Annotate the CommonJS export names for ESM import in node:
295
599
  0 && (module.exports = {
600
+ allowAuthAdminOrPerm,
601
+ allowSysAdminOrAnyPermission,
602
+ allowSysAdminOrPermissionsAll,
603
+ allowSysAdminOrRoles,
604
+ allowSysAdminOrRolesOrAnyPermission,
296
605
  internalAuth,
297
606
  parseHeaders,
298
607
  requestId,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/middlewares/index.ts","../../src/headers/constants.ts","../../src/headers/parse.ts","../../src/middlewares/parseHeaders.ts","../../src/middlewares/requestId.ts","../../src/middlewares/internalAuth.ts","../../src/middlewares/respond.ts","../../src/middlewares/authorization.ts"],"sourcesContent":["// packages/sdk/src/middlewares/index.ts\n\nexport {default as parseHeaders} from \"./parseHeaders\";\nexport {default as requestId} from \"./requestId\";\nexport {default as internalAuth} from \"./internalAuth\";\nexport {sendOk, sendError} from \"./respond\";\n\n// authorization helpers\nexport * from \"./authorization\";\n","export const HEADER_REQUEST_ID = \"x-request-id\";\n\nexport const HEADER_COMPANY_UID = \"x-company\";\nexport const HEADER_BRANCH_UID = \"x-branch\";\nexport const HEADER_EMPLOYEE_UID = \"x-employee-uid\";\n\nexport const HEADER_INTERNAL_API_KEY = \"x-internal-api-key\";\nexport const HEADER_AUTHORIZATION = \"authorization\";\n","import {\n HEADER_BRANCH_UID,\n HEADER_COMPANY_UID,\n HEADER_EMPLOYEE_UID,\n HEADER_REQUEST_ID,\n} from \"./constants\";\n\nexport type RequestContext = {\n requestId?: string | null;\n company_uid?: string | null;\n branch_uid?: string | null;\n employee_uid?: string | null;\n};\n\nfunction normalizeHeaderValue(v: unknown): string | null {\n if (typeof v !== \"string\") return null;\n const s = v.trim();\n if (!s) return null;\n\n // ✅ NO-LEGACY: bloquea JSON en headers\n if (s.startsWith(\"{\") || s.startsWith(\"[\") || s.includes('\"')) return null;\n\n // Evitar valores demasiado cortos (basura)\n if (s.length < 6) return null;\n\n return s;\n}\n\n/**\n * Lee header aunque venga en mayúsculas/minúsculas (Express suele bajar a lower-case).\n */\nfunction h(headers: Record<string, any>, key: string): unknown {\n return headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];\n}\n\n/**\n * ✅ NO-LEGACY:\n * - x-company: <UID>\n * - x-branch: <UID>\n * - x-employee-uid: <UID> (opcional; NO reemplaza JWT)\n * - x-request-id: string (opcional)\n */\nexport function getRequestContextFromHeaders(headers: Record<string, any>): RequestContext {\n return {\n requestId: normalizeHeaderValue(h(headers, HEADER_REQUEST_ID)) ?? null,\n company_uid: normalizeHeaderValue(h(headers, HEADER_COMPANY_UID)) ?? null,\n branch_uid: normalizeHeaderValue(h(headers, HEADER_BRANCH_UID)) ?? null,\n employee_uid: normalizeHeaderValue(h(headers, HEADER_EMPLOYEE_UID)) ?? null,\n };\n}\n","// sdk/src/middlewares/parseHeaders.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {getRequestContextFromHeaders} from \"../headers\";\n\n/**\n * ✅ NO-LEGACY / ESTÁNDAR:\n * - Lee SOLO x-company y x-branch (UIDs planos)\n * - Setea req.context = { company_uid, branch_uid }\n * - NO toca req.auth (auth lo setea authentication/requireAuth)\n */\nexport default function parseHeaders(req: Request, _res: Response, next: NextFunction) {\n (req as any).context = getRequestContextFromHeaders(req.headers as any);\n next();\n}\n","// middlewares/requestId.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {randomUUID, randomBytes} from \"crypto\";\n\nexport const REQUEST_ID_HEADER = \"x-request-id\";\nexport const REQUEST_ID_HEADER_ALT = \"x-requestid\";\nexport const RESPONSE_REQUEST_ID_HEADER = \"X-Request-Id\";\n\n// Si quieres IDs más cortos (opcional). Por defecto usamos UUID.\nfunction nanoidLike(len = 21) {\n return randomBytes(16).toString(\"base64url\").slice(0, len);\n}\n\nexport default function requestId(req: Request, res: Response, next: NextFunction) {\n const headerId = (req.headers[REQUEST_ID_HEADER] || req.headers[REQUEST_ID_HEADER_ALT]) as\n | string\n | undefined;\n\n // ✅ estándar único: usa UUID (o cambia a nanoidLike() si prefieres corto)\n const id = headerId?.trim() || randomUUID();\n\n // ✅ estándar único (no legacy)\n (req as any).requestId = id;\n res.locals.requestId = id;\n\n // ✅ respuesta\n res.setHeader(RESPONSE_REQUEST_ID_HEADER, id);\n\n next();\n}\n","import type {Request, Response, NextFunction} from \"express\";\nimport fs from \"fs\";\nimport crypto from \"crypto\";\nimport {sendError} from \"./respond\";\nimport {HEADER_INTERNAL_API_KEY} from \"../headers\";\n\nfunction readSecretFile(path?: string): string | null {\n if (!path) return null;\n try {\n const v = fs.readFileSync(path, \"utf8\").trim();\n return v.length ? v : null;\n } catch {\n return null;\n }\n}\n\nfunction splitKeys(v?: string | null): string[] {\n if (!v) return [];\n return v.split(\",\").map((s) => s.trim()).filter(Boolean);\n}\n\nfunction getExpectedKeys(): string[] {\n const fileKey = readSecretFile(process.env.INTERNAL_API_KEY_FILE);\n const envKey = (process.env.INTERNAL_API_KEY || \"\").trim();\n const raw = fileKey || envKey;\n return splitKeys(raw);\n}\n\nfunction extractToken(req: Request): string | null {\n const apiKey = (req.header(HEADER_INTERNAL_API_KEY) || \"\").trim();\n return apiKey || null;\n}\n\nfunction safeEquals(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n if (aa.length !== bb.length) return false;\n return crypto.timingSafeEqual(aa, bb);\n}\n\nexport default function internalAuth(req: Request, res: Response, next: NextFunction) {\n const token = extractToken(req);\n\n if (!token) {\n return sendError(req, res, 401, \"UNAUTHORIZED\", `Missing internal api key (${HEADER_INTERNAL_API_KEY})`);\n }\n\n const expectedKeys = getExpectedKeys();\n if (expectedKeys.length === 0) {\n return sendError(\n req,\n res,\n 500,\n \"MISCONFIGURED_INTERNAL_AUTH\",\n \"Internal api key not configured (INTERNAL_API_KEY or INTERNAL_API_KEY_FILE)\"\n );\n }\n\n const ok = expectedKeys.some((k) => safeEquals(token, k));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Invalid internal api key\");\n }\n\n return next();\n}\n","import type {Request, Response} from \"express\";\n\nexport function sendOk<T>(_req: Request, res: Response, data: T, statusCode = 200) {\n return res.status(statusCode).json({ok: true, data, requestId: res.locals?.requestId ?? null});\n}\n\nexport function sendError(\n _req: Request,\n res: Response,\n statusCode: number,\n code: string,\n message: string,\n details?: any\n) {\n return res.status(statusCode).json({\n ok: false,\n error: {code, message, ...(details !== undefined ? {details} : {})},\n requestId: res.locals?.requestId ?? null,\n });\n}\n","// packages/sdk/src/middlewares/authorization.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {sendError} from \"./respond\";\n\ntype AuthRole = string | { code?: string; name?: string };\ntype AuthPermission = string | { code?: string; name?: string };\n\ntype AuthShape = {\n roles?: AuthRole[];\n permissions?: AuthPermission[];\n denied_permissions?: AuthPermission[];\n};\n\nfunction getAuth(req: Request): AuthShape {\n return ((req as any).auth ?? {}) as AuthShape;\n}\n\nfunction normalizeCode(v: any): string | null {\n if (!v) return null;\n if (typeof v === \"string\") return v;\n if (typeof v === \"object\") return v.code || v.name || null;\n return null;\n}\n\nfunction rolesSet(auth: AuthShape): Set<string> {\n const out = new Set<string>();\n for (const r of auth.roles || []) {\n const c = normalizeCode(r);\n if (c) out.add(c);\n }\n return out;\n}\n\nfunction permsSet(list?: AuthPermission[]): Set<string> {\n const out = new Set<string>();\n for (const p of list || []) {\n const c = normalizeCode(p);\n if (c) out.add(c);\n }\n return out;\n}\n\n/**\n * 401 si no existe req.auth (contexto auth).\n * Útil para proteger rutas donde SIEMPRE debe existir auth.\n */\nexport function requireAuthContext() {\n return (req: Request, res: Response, next: NextFunction) => {\n if (!(req as any).auth) {\n return sendError(req, res, 401, \"UNAUTHORIZED\", \"Missing auth context\");\n }\n return next();\n };\n}\n\n/**\n * Helper: SYS_ADMIN bypass (por defecto activo)\n */\nfunction isSysAdmin(auth: AuthShape, sysAdminRole: string) {\n const have = rolesSet(auth);\n return have.has(sysAdminRole);\n}\n\n/**\n * Requiere TODOS los permisos indicados.\n * Regla: denied_permissions siempre gana sobre permissions.\n *\n * options:\n * - sysAdminBypass: default true\n * - sysAdminRole: default \"SYS_ADMIN\"\n */\nexport function requirePermissions(\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const missing = perms.filter((p) => !allow.has(p));\n if (missing.length) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Missing permissions\", {\n missing,\n mode: \"ALL\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere AL MENOS 1 permiso de la lista (ANY/OR).\n * Regla: denied_permissions siempre gana.\n */\nexport function requireAnyPermission(\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre (si alguno requerido está denegado explícitamente)\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const ok = perms.some((p) => allow.has(p));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Permission denied\", {\n required: perms,\n mode: \"ANY\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere al menos 1 rol (ANY/OR).\n * options:\n * - sysAdminBypass: default true\n * - sysAdminRole: default \"SYS_ADMIN\"\n */\nexport function requireRoles(\n roles: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n // SYS_ADMIN bypass aplica también aquí\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const have = rolesSet(auth);\n if (!roles.some((r) => have.has(r))) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Role not allowed\", {\n required: roles,\n mode: \"ANY\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere (roles ANY) OR (permissions ANY).\n * deny_permissions siempre gana sobre permissions.\n */\nexport function requireRolesOrAnyPermission(\n roles: string[],\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const haveRoles = rolesSet(auth);\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre (si cualquiera de los permisos evaluados está denegado explícitamente)\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const okRole = roles.some((r) => haveRoles.has(r));\n const okPerm = perms.some((p) => allow.has(p));\n\n if (!okRole && !okPerm) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Access denied\", {\n roles,\n permissions: perms,\n mode: \"ROLES_OR_PERMS_ANY\",\n });\n }\n\n return next();\n };\n}\n"],"mappings":"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","names":["import_crypto","fs","crypto"]}
1
+ {"version":3,"sources":["../../src/middlewares/index.ts","../../src/headers/constants.ts","../../src/headers/parse.ts","../../src/middlewares/parseHeaders.ts","../../src/middlewares/requestId.ts","../../src/middlewares/internalAuth.ts","../../src/middlewares/respond.ts","../../src/middlewares/authorization.ts","../../src/auth/jwt.ts","../../src/auth/authentication.ts","../../src/middlewares/guards.ts","../../src/middlewares/accessControl.ts"],"sourcesContent":["// packages/sdk/src/middlewares/index.ts\nexport {default as parseHeaders} from \"./parseHeaders\";\nexport {default as requestId} from \"./requestId\";\nexport {default as internalAuth} from \"./internalAuth\";\n\nexport {sendOk, sendError} from \"./respond\";\n\nexport * from \"./authorization\";\nexport * from \"./guards\";\nexport * from \"./accessControl\";\n","export const HEADER_REQUEST_ID = \"x-request-id\";\n\nexport const HEADER_COMPANY_UID = \"x-company\";\nexport const HEADER_BRANCH_UID = \"x-branch\";\nexport const HEADER_EMPLOYEE_UID = \"x-employee-uid\";\n\nexport const HEADER_INTERNAL_API_KEY = \"x-internal-api-key\";\nexport const HEADER_AUTHORIZATION = \"authorization\";\n","import {\n HEADER_BRANCH_UID,\n HEADER_COMPANY_UID,\n HEADER_EMPLOYEE_UID,\n HEADER_REQUEST_ID,\n} from \"./constants\";\n\nexport type RequestContext = {\n requestId?: string | null;\n company_uid?: string | null;\n branch_uid?: string | null;\n employee_uid?: string | null;\n};\n\nfunction normalizeHeaderValue(v: unknown): string | null {\n if (typeof v !== \"string\") return null;\n const s = v.trim();\n if (!s) return null;\n\n // ✅ NO-LEGACY: bloquea JSON en headers\n if (s.startsWith(\"{\") || s.startsWith(\"[\") || s.includes('\"')) return null;\n\n // Evitar valores demasiado cortos (basura)\n if (s.length < 6) return null;\n\n return s;\n}\n\n/**\n * Lee header aunque venga en mayúsculas/minúsculas (Express suele bajar a lower-case).\n */\nfunction h(headers: Record<string, any>, key: string): unknown {\n return headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];\n}\n\n/**\n * ✅ NO-LEGACY:\n * - x-company: <UID>\n * - x-branch: <UID>\n * - x-employee-uid: <UID> (opcional; NO reemplaza JWT)\n * - x-request-id: string (opcional)\n */\nexport function getRequestContextFromHeaders(headers: Record<string, any>): RequestContext {\n return {\n requestId: normalizeHeaderValue(h(headers, HEADER_REQUEST_ID)) ?? null,\n company_uid: normalizeHeaderValue(h(headers, HEADER_COMPANY_UID)) ?? null,\n branch_uid: normalizeHeaderValue(h(headers, HEADER_BRANCH_UID)) ?? null,\n employee_uid: normalizeHeaderValue(h(headers, HEADER_EMPLOYEE_UID)) ?? null,\n };\n}\n","// sdk/src/middlewares/parseHeaders.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {getRequestContextFromHeaders} from \"../headers\";\n\n/**\n * ✅ NO-LEGACY / ESTÁNDAR:\n * - Lee SOLO x-company y x-branch (UIDs planos)\n * - Setea req.context = { company_uid, branch_uid }\n * - NO toca req.auth (auth lo setea authentication/requireAuth)\n */\nexport default function parseHeaders(req: Request, _res: Response, next: NextFunction) {\n (req as any).context = getRequestContextFromHeaders(req.headers as any);\n next();\n}\n","// middlewares/requestId.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {randomUUID, randomBytes} from \"crypto\";\n\nexport const REQUEST_ID_HEADER = \"x-request-id\";\nexport const REQUEST_ID_HEADER_ALT = \"x-requestid\";\nexport const RESPONSE_REQUEST_ID_HEADER = \"X-Request-Id\";\n\n// Si quieres IDs más cortos (opcional). Por defecto usamos UUID.\nfunction nanoidLike(len = 21) {\n return randomBytes(16).toString(\"base64url\").slice(0, len);\n}\n\nexport default function requestId(req: Request, res: Response, next: NextFunction) {\n const headerId = (req.headers[REQUEST_ID_HEADER] || req.headers[REQUEST_ID_HEADER_ALT]) as\n | string\n | undefined;\n\n // ✅ estándar único: usa UUID (o cambia a nanoidLike() si prefieres corto)\n const id = headerId?.trim() || randomUUID();\n\n // ✅ estándar único (no legacy)\n (req as any).requestId = id;\n res.locals.requestId = id;\n\n // ✅ respuesta\n res.setHeader(RESPONSE_REQUEST_ID_HEADER, id);\n\n next();\n}\n","import type {Request, Response, NextFunction} from \"express\";\nimport fs from \"fs\";\nimport crypto from \"crypto\";\nimport {sendError} from \"./respond\";\nimport {HEADER_INTERNAL_API_KEY} from \"../headers\";\n\nfunction readSecretFile(path?: string): string | null {\n if (!path) return null;\n try {\n const v = fs.readFileSync(path, \"utf8\").trim();\n return v.length ? v : null;\n } catch {\n return null;\n }\n}\n\nfunction splitKeys(v?: string | null): string[] {\n if (!v) return [];\n return v.split(\",\").map((s) => s.trim()).filter(Boolean);\n}\n\nfunction getExpectedKeys(): string[] {\n const fileKey = readSecretFile(process.env.INTERNAL_API_KEY_FILE);\n const envKey = (process.env.INTERNAL_API_KEY || \"\").trim();\n const raw = fileKey || envKey;\n return splitKeys(raw);\n}\n\nfunction extractToken(req: Request): string | null {\n const apiKey = (req.header(HEADER_INTERNAL_API_KEY) || \"\").trim();\n return apiKey || null;\n}\n\nfunction safeEquals(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n if (aa.length !== bb.length) return false;\n return crypto.timingSafeEqual(aa, bb);\n}\n\nexport default function internalAuth(req: Request, res: Response, next: NextFunction) {\n const token = extractToken(req);\n\n if (!token) {\n return sendError(req, res, 401, \"UNAUTHORIZED\", `Missing internal api key (${HEADER_INTERNAL_API_KEY})`);\n }\n\n const expectedKeys = getExpectedKeys();\n if (expectedKeys.length === 0) {\n return sendError(\n req,\n res,\n 500,\n \"MISCONFIGURED_INTERNAL_AUTH\",\n \"Internal api key not configured (INTERNAL_API_KEY or INTERNAL_API_KEY_FILE)\"\n );\n }\n\n const ok = expectedKeys.some((k) => safeEquals(token, k));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Invalid internal api key\");\n }\n\n return next();\n}\n","import type {Request, Response} from \"express\";\n\nexport function sendOk<T>(_req: Request, res: Response, data: T, statusCode = 200) {\n return res.status(statusCode).json({ok: true, data, requestId: res.locals?.requestId ?? null});\n}\n\nexport function sendError(\n _req: Request,\n res: Response,\n statusCode: number,\n code: string,\n message: string,\n details?: any\n) {\n return res.status(statusCode).json({\n ok: false,\n error: {code, message, ...(details !== undefined ? {details} : {})},\n requestId: res.locals?.requestId ?? null,\n });\n}\n","// packages/sdk/src/middlewares/authorization.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {sendError} from \"./respond\";\n\ntype AuthRole = string | { code?: string; name?: string };\ntype AuthPermission = string | { code?: string; name?: string };\n\ntype AuthShape = {\n roles?: AuthRole[];\n permissions?: AuthPermission[];\n denied_permissions?: AuthPermission[];\n};\n\nfunction getAuth(req: Request): AuthShape {\n return ((req as any).auth ?? {}) as AuthShape;\n}\n\nfunction normalizeCode(v: any): string | null {\n if (!v) return null;\n if (typeof v === \"string\") return v;\n if (typeof v === \"object\") return v.code || v.name || null;\n return null;\n}\n\nfunction rolesSet(auth: AuthShape): Set<string> {\n const out = new Set<string>();\n for (const r of auth.roles || []) {\n const c = normalizeCode(r);\n if (c) out.add(c);\n }\n return out;\n}\n\nfunction permsSet(list?: AuthPermission[]): Set<string> {\n const out = new Set<string>();\n for (const p of list || []) {\n const c = normalizeCode(p);\n if (c) out.add(c);\n }\n return out;\n}\n\n/**\n * 401 si no existe req.auth (contexto auth).\n * Útil para proteger rutas donde SIEMPRE debe existir auth.\n */\nexport function requireAuthContext() {\n return (req: Request, res: Response, next: NextFunction) => {\n if (!(req as any).auth) {\n return sendError(req, res, 401, \"UNAUTHORIZED\", \"Missing auth context\");\n }\n return next();\n };\n}\n\n/**\n * Helper: SYS_ADMIN bypass (por defecto activo)\n */\nfunction isSysAdmin(auth: AuthShape, sysAdminRole: string) {\n const have = rolesSet(auth);\n return have.has(sysAdminRole);\n}\n\n/**\n * Requiere TODOS los permisos indicados.\n * Regla: denied_permissions siempre gana sobre permissions.\n *\n * options:\n * - sysAdminBypass: default true\n * - sysAdminRole: default \"SYS_ADMIN\"\n */\nexport function requirePermissions(\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const missing = perms.filter((p) => !allow.has(p));\n if (missing.length) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Missing permissions\", {\n missing,\n mode: \"ALL\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere AL MENOS 1 permiso de la lista (ANY/OR).\n * Regla: denied_permissions siempre gana.\n */\nexport function requireAnyPermission(\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre (si alguno requerido está denegado explícitamente)\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const ok = perms.some((p) => allow.has(p));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Permission denied\", {\n required: perms,\n mode: \"ANY\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere al menos 1 rol (ANY/OR).\n * options:\n * - sysAdminBypass: default true\n * - sysAdminRole: default \"SYS_ADMIN\"\n */\nexport function requireRoles(\n roles: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n // SYS_ADMIN bypass aplica también aquí\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const have = rolesSet(auth);\n if (!roles.some((r) => have.has(r))) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Role not allowed\", {\n required: roles,\n mode: \"ANY\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere (roles ANY) OR (permissions ANY).\n * deny_permissions siempre gana sobre permissions.\n */\nexport function requireRolesOrAnyPermission(\n roles: string[],\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const haveRoles = rolesSet(auth);\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre (si cualquiera de los permisos evaluados está denegado explícitamente)\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const okRole = roles.some((r) => haveRoles.has(r));\n const okPerm = perms.some((p) => allow.has(p));\n\n if (!okRole && !okPerm) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Access denied\", {\n roles,\n permissions: perms,\n mode: \"ROLES_OR_PERMS_ANY\",\n });\n }\n\n return next();\n };\n}\n","import fs from \"fs\";\nimport jwt, {JwtPayload} from \"jsonwebtoken\";\n\nfunction readFileIfExists(path?: string): string | null {\n if (!path) return null;\n try {\n const v = fs.readFileSync(path, \"utf8\").trim();\n return v.length ? v : null;\n } catch {\n return null;\n }\n}\n\n/**\n * ✅ Keys viven en getmarket-stack:\n * - JWT_PUBLIC_KEY_PATH=/run/secrets/jwtRS256.key.pub (recomendado)\n * - fallback env AUTH_JWT_PUBLIC_KEY / AUTH_RSA_PUBLIC_KEY\n */\nexport function readRs256PublicKey(): string {\n const fromFile = readFileIfExists(process.env.JWT_PUBLIC_KEY_PATH);\n if (fromFile) return fromFile;\n\n const fromEnv = String(process.env.AUTH_JWT_PUBLIC_KEY || process.env.AUTH_RSA_PUBLIC_KEY || \"\")\n .replace(/\\\\n/g, \"\\n\")\n .trim();\n\n if (fromEnv) return fromEnv;\n\n throw new Error(\"Missing RS256 public key (JWT_PUBLIC_KEY_PATH / AUTH_JWT_PUBLIC_KEY / AUTH_RSA_PUBLIC_KEY)\");\n}\n\nexport function verifyBackendJwtRS256(raw: string): JwtPayload {\n const publicKey = readRs256PublicKey();\n\n const audience = process.env.JWT_AUDIENCE || process.env.AUTH_JWT_AUDIENCE || \"getmarket.api\";\n const issuer = process.env.JWT_ISSUER || process.env.AUTH_JWT_ISSUER || \"getmarket-auth\";\n\n // ✅ SOLO RS256\n return jwt.verify(raw, publicKey, {\n algorithms: [\"RS256\"],\n audience,\n issuer,\n }) as JwtPayload;\n}\n","// packages/sdk/src/auth/authentication.ts\nimport type {NextFunction, Response} from \"express\";\nimport admin from \"firebase-admin\";\nimport jwt, {JwtPayload} from \"jsonwebtoken\";\nimport fs from \"fs\";\n\ntype Subject = \"employee\" | \"customer\";\ntype TokenType = \"backend\";\n\nexport interface AuthContext {\n tokenType: TokenType;\n subject: Subject;\n\n employee?: any;\n customer?: any;\n\n company_uid?: string;\n branch_uid?: string;\n\n company?: any;\n branch?: any;\n companies?: any[];\n\n roles?: string[];\n permissions?: string[];\n denied_permissions?: string[];\n\n session?: { jti?: string; device_id?: string; expires_at?: number };\n firebase?: admin.auth.DecodedIdToken;\n}\n\n/**\n * ✅ ÚNICO estándar:\n * - Authorization: Bearer <token>\n */\nfunction getBearerToken(req: any): string | null {\n const auth = String(req.headers?.authorization || \"\");\n if (!auth.startsWith(\"Bearer \")) return null;\n const token = auth.slice(7).trim();\n return token.length ? token : null;\n}\n\nfunction readPublicKey(): string {\n const publicKeyPath = process.env.JWT_PUBLIC_KEY_PATH;\n const publicKeyEnv = process.env.AUTH_JWT_PUBLIC_KEY || process.env.AUTH_RSA_PUBLIC_KEY || \"\";\n\n if (publicKeyPath) {\n const v = fs.readFileSync(publicKeyPath, \"utf8\").trim();\n if (v) return v;\n }\n\n const envKey = publicKeyEnv.replace(/\\\\n/g, \"\\n\").trim();\n if (envKey) return envKey;\n\n throw new Error(\n \"Missing RS256 public key (JWT_PUBLIC_KEY_PATH / AUTH_JWT_PUBLIC_KEY / AUTH_RSA_PUBLIC_KEY)\"\n );\n}\n\nfunction verifyBackendJwtRS256(raw: string): JwtPayload {\n const publicKey = readPublicKey();\n const audience = process.env.JWT_AUDIENCE || process.env.AUTH_JWT_AUDIENCE || \"getmarket.api\";\n const issuer = process.env.JWT_ISSUER || process.env.AUTH_JWT_ISSUER || \"getmarket-auth\";\n\n return jwt.verify(raw, publicKey, {\n algorithms: [\"RS256\"],\n audience,\n issuer,\n }) as JwtPayload;\n}\n\nfunction normalizeUid(v: any): string | null {\n const s = String(v ?? \"\").trim();\n return s.length ? s : null;\n}\n\nfunction deriveCompanyBranch(decoded: any, companyUid: string | null, branchUid: string | null) {\n const companiesFromToken = Array.isArray(decoded?.companies) ? decoded.companies : [];\n\n const company =\n decoded?.company ??\n (companyUid ? companiesFromToken.find((c: any) => c?.uid === companyUid) : null) ??\n null;\n\n const branch =\n decoded?.branch ??\n (branchUid && company?.branches ? (company.branches || []).find((b: any) => b?.uid === branchUid) : null) ??\n null;\n\n return {companiesFromToken, company, branch};\n}\n\nexport function createAuthMiddleware(opts: { subject: Subject; allowFirebaseIdToken?: boolean }) {\n const {subject, allowFirebaseIdToken = false} = opts;\n\n return async (req: any, res: Response, next: NextFunction) => {\n const token = getBearerToken(req);\n if (!token) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_MISSING_TOKEN\",\n message: \"Missing Authorization Bearer token\",\n });\n }\n\n try {\n const decoded: any = verifyBackendJwtRS256(token);\n\n const headerCtx = (req as any).context || {};\n const companyUid = normalizeUid(headerCtx.company_uid);\n const branchUid = normalizeUid(headerCtx.branch_uid);\n\n const {companiesFromToken, company, branch} = deriveCompanyBranch(decoded, companyUid, branchUid);\n\n const ctx: AuthContext = {\n tokenType: \"backend\",\n subject,\n\n company_uid: companyUid ?? undefined,\n branch_uid: branchUid ?? undefined,\n\n companies: companiesFromToken,\n company,\n branch,\n\n roles: Array.isArray(decoded?.roles) ? decoded.roles : [],\n permissions: Array.isArray(decoded?.permissions) ? decoded.permissions : [],\n denied_permissions: Array.isArray(decoded?.denied_permissions) ? decoded.denied_permissions : [],\n\n session: {\n jti: decoded?.jti,\n device_id: decoded?.device_id,\n expires_at: decoded?.exp,\n },\n };\n\n if (subject === \"employee\") {\n const employee = decoded?.employee ?? decoded?.user ?? null;\n if (!employee) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_EMPLOYEE_NOT_FOUND\",\n message: \"Employee not found in token\",\n });\n }\n ctx.employee = employee;\n } else {\n const customer = decoded?.customer ?? null;\n if (!customer) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_CUSTOMER_NOT_FOUND\",\n message: \"Customer not found in token\",\n });\n }\n ctx.customer = customer;\n }\n\n req.auth = ctx; // runtime OK\n return next();\n } catch {\n if (!allowFirebaseIdToken) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_INVALID_TOKEN\",\n message: \"Invalid or expired token\",\n });\n }\n\n try {\n const firebaseDecoded = await admin.auth().verifyIdToken(token);\n\n if (firebaseDecoded.email && firebaseDecoded.email_verified === false) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_EMAIL_NOT_VERIFIED\",\n message: \"Email not verified\",\n });\n }\n\n const headerCtx = (req as any).context || {};\n const companyUid = normalizeUid(headerCtx.company_uid);\n const branchUid = normalizeUid(headerCtx.branch_uid);\n\n req.auth = {\n tokenType: \"backend\",\n subject,\n firebase: firebaseDecoded,\n company_uid: companyUid ?? undefined,\n branch_uid: branchUid ?? undefined,\n companies: [],\n roles: [],\n permissions: [],\n denied_permissions: [],\n };\n\n return next();\n } catch {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_INVALID_TOKEN\",\n message: \"Invalid or expired token\",\n });\n }\n }\n };\n}\n\nexport const authEmployeeRequired = createAuthMiddleware({subject: \"employee\", allowFirebaseIdToken: false});\nexport const authCustomerRequired = createAuthMiddleware({subject: \"customer\", allowFirebaseIdToken: false});\nexport const authEmployeeAllowFirebase = createAuthMiddleware({subject: \"employee\", allowFirebaseIdToken: true});\nexport const authCustomerAllowFirebase = createAuthMiddleware({subject: \"customer\", allowFirebaseIdToken: true});\n","import type {Request, Response, NextFunction, RequestHandler} from \"express\";\nimport parseHeaders from \"./parseHeaders\";\nimport {authEmployeeRequired} from \"../auth\";\nimport {sendError} from \"./respond\";\n\ntype RoleShape = string | { code?: string; name?: string };\ntype PermShape = string | { code?: string; name?: string };\n\nfunction normalizeRole(r: RoleShape): string | null {\n if (!r) return null;\n if (typeof r === \"string\") return r;\n return (r.code || r.name || null) as any;\n}\n\nfunction normalizePerm(p: PermShape): string | null {\n if (!p) return null;\n if (typeof p === \"string\") return p;\n return (p.code || p.name || null) as any;\n}\n\nfunction isSysAdmin(roles: RoleShape[] | undefined): boolean {\n if (!Array.isArray(roles)) return false;\n return roles.some((r) => normalizeRole(r) === \"SYS_ADMIN\");\n}\n\nfunction getAuth(req: Request) {\n return ((req as any).auth ?? {}) as {\n roles?: RoleShape[];\n permissions?: PermShape[];\n denied_permissions?: PermShape[];\n };\n}\n\nfunction permissionSets(auth: ReturnType<typeof getAuth>) {\n const allow = new Set<string>(\n (auth.permissions ?? []).map(normalizePerm).filter(Boolean) as string[]\n );\n const deny = new Set<string>(\n (auth.denied_permissions ?? []).map(normalizePerm).filter(Boolean) as string[]\n );\n return {allow, deny};\n}\n\n/**\n * ✅ SysAdmin bypass OR (ANY) permissions\n * - Si tiene alguno de los permisos => OK\n * - denied_permissions gana siempre\n */\nexport function allowSysAdminOrAnyPermission(...perms: string[]): RequestHandler[] {\n const required = (perms ?? []).filter(Boolean);\n\n return [\n parseHeaders,\n authEmployeeRequired,\n (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n if (isSysAdmin(auth.roles)) return next();\n\n const {allow, deny} = permissionSets(auth);\n\n for (const p of required) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const ok = required.some((p) => allow.has(p));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Missing permissions (ANY)\", {\n required,\n });\n }\n\n return next();\n },\n ];\n}\n\n/**\n * ✅ SysAdmin bypass OR (ALL) permissions (AND)\n * - Debe tener TODOS los permisos requeridos\n * - denied_permissions gana siempre\n */\nexport function allowSysAdminOrPermissionsAll(...perms: string[]): RequestHandler[] {\n const required = (perms ?? []).filter(Boolean);\n\n return [\n parseHeaders,\n authEmployeeRequired,\n (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n if (isSysAdmin(auth.roles)) return next();\n\n const {allow, deny} = permissionSets(auth);\n\n for (const p of required) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const missing = required.filter((p) => !allow.has(p));\n if (missing.length) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Missing permissions (ALL)\", {\n required,\n missing,\n });\n }\n\n return next();\n },\n ];\n}\n\n/**\n * ✅ SysAdmin bypass OR roles (ANY)\n */\nexport function allowSysAdminOrRoles(...roles: string[]): RequestHandler[] {\n const required = (roles ?? []).filter(Boolean);\n\n return [\n parseHeaders,\n authEmployeeRequired,\n (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n if (isSysAdmin(auth.roles)) return next();\n\n const have = new Set<string>(\n (auth.roles ?? []).map(normalizeRole).filter(Boolean) as string[]\n );\n\n const ok = required.some((r) => have.has(r));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Role not allowed\", {\n required,\n });\n }\n\n return next();\n },\n ];\n}\n","// packages/sdk/src/middlewares/accessControl.ts\nimport type {RequestHandler} from \"express\";\nimport parseHeaders from \"./parseHeaders\";\nimport {authEmployeeRequired} from \"../auth\";\nimport {sendError} from \"./respond\";\n\ntype RoleShape = string | { code?: string; name?: string };\ntype PermissionShape = string | { code?: string; name?: string };\n\nfunction normalizeList<T>(v: T | T[]): T[] {\n return Array.isArray(v) ? v : [v];\n}\n\nfunction roleCode(r: RoleShape): string | null {\n if (!r) return null;\n return typeof r === \"string\" ? r : (r.code || r.name || null);\n}\n\nfunction permCode(p: PermissionShape): string | null {\n if (!p) return null;\n return typeof p === \"string\" ? p : (p.code || p.name || null);\n}\n\nfunction isSysAdmin(roles: RoleShape[] | undefined): boolean {\n if (!Array.isArray(roles)) return false;\n return roles.map(roleCode).filter(Boolean).includes(\"SYS_ADMIN\");\n}\n\n/**\n * ✅ SYS_ADMIN bypass OR (ANY) roles OR (ANY) permissions\n * - parseHeaders + authEmployeeRequired incluidos\n * - denied_permissions siempre gana\n */\nexport function allowSysAdminOrRolesOrAnyPermission(\n roles: string | string[],\n permissions: string | string[]\n): RequestHandler[] {\n const requiredRoles = normalizeList(roles).filter(Boolean);\n const requiredPerms = normalizeList(permissions).filter(Boolean);\n\n return [\n parseHeaders,\n authEmployeeRequired,\n (req, res, next) => {\n const auth: any = (req as any).auth || {};\n\n // SYS_ADMIN bypass\n if (isSysAdmin(auth.roles)) return next();\n\n // denied_permissions gana\n const deny = new Set<string>((auth.denied_permissions || []).map(permCode).filter(Boolean) as string[]);\n for (const p of requiredPerms) {\n if (deny.has(p)) {\n return sendError(req as any, res as any, 403, \"FORBIDDEN\", `Denied: ${p}`, {permission: p});\n }\n }\n\n // roles ANY\n const haveRoles = new Set<string>((auth.roles || []).map(roleCode).filter(Boolean) as string[]);\n if (requiredRoles.some((r) => haveRoles.has(r))) return next();\n\n // permissions ANY\n const havePerms = new Set<string>((auth.permissions || []).map(permCode).filter(Boolean) as string[]);\n if (requiredPerms.some((p) => havePerms.has(p))) return next();\n\n return sendError(req as any, res as any, 403, \"FORBIDDEN\", \"Permission denied\", {\n roles: requiredRoles,\n permissions: requiredPerms,\n mode: \"ROLES_OR_ANY_PERMISSION\",\n });\n },\n ];\n}\n\n/**\n * ✅ Helper específico para el caso del Auth:\n * Rol AUTH_ADMIN o permiso fino (y SYS_ADMIN bypass)\n */\nexport function allowAuthAdminOrPerm(permission: string): RequestHandler[] {\n return allowSysAdminOrRolesOrAnyPermission([\"AUTH_ADMIN\"], [permission]);\n}\n"],"mappings":"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","names":["import_crypto","fs","crypto","import_jsonwebtoken","import_fs","fs","verifyBackendJwtRS256","jwt","admin","isSysAdmin","getAuth","isSysAdmin"]}
@@ -1,4 +1,4 @@
1
- import { Request, Response, NextFunction } from 'express';
1
+ import { Request, Response, NextFunction, RequestHandler } from 'express';
2
2
 
3
3
  /**
4
4
  * ✅ NO-LEGACY / ESTÁNDAR:
@@ -59,4 +59,33 @@ declare function requireRolesOrAnyPermission(roles: string[], perms: string[], o
59
59
  sysAdminRole?: string;
60
60
  }): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
61
61
 
62
- export { internalAuth, parseHeaders, requestId, requireAnyPermission, requireAuthContext, requirePermissions, requireRoles, requireRolesOrAnyPermission, sendError, sendOk };
62
+ /**
63
+ * ✅ SysAdmin bypass OR (ANY) permissions
64
+ * - Si tiene alguno de los permisos => OK
65
+ * - denied_permissions gana siempre
66
+ */
67
+ declare function allowSysAdminOrAnyPermission(...perms: string[]): RequestHandler[];
68
+ /**
69
+ * ✅ SysAdmin bypass OR (ALL) permissions (AND)
70
+ * - Debe tener TODOS los permisos requeridos
71
+ * - denied_permissions gana siempre
72
+ */
73
+ declare function allowSysAdminOrPermissionsAll(...perms: string[]): RequestHandler[];
74
+ /**
75
+ * ✅ SysAdmin bypass OR roles (ANY)
76
+ */
77
+ declare function allowSysAdminOrRoles(...roles: string[]): RequestHandler[];
78
+
79
+ /**
80
+ * ✅ SYS_ADMIN bypass OR (ANY) roles OR (ANY) permissions
81
+ * - parseHeaders + authEmployeeRequired incluidos
82
+ * - denied_permissions siempre gana
83
+ */
84
+ declare function allowSysAdminOrRolesOrAnyPermission(roles: string | string[], permissions: string | string[]): RequestHandler[];
85
+ /**
86
+ * ✅ Helper específico para el caso del Auth:
87
+ * Rol AUTH_ADMIN o permiso fino (y SYS_ADMIN bypass)
88
+ */
89
+ declare function allowAuthAdminOrPerm(permission: string): RequestHandler[];
90
+
91
+ export { allowAuthAdminOrPerm, allowSysAdminOrAnyPermission, allowSysAdminOrPermissionsAll, allowSysAdminOrRoles, allowSysAdminOrRolesOrAnyPermission, internalAuth, parseHeaders, requestId, requireAnyPermission, requireAuthContext, requirePermissions, requireRoles, requireRolesOrAnyPermission, sendError, sendOk };
@@ -1,4 +1,4 @@
1
- import { Request, Response, NextFunction } from 'express';
1
+ import { Request, Response, NextFunction, RequestHandler } from 'express';
2
2
 
3
3
  /**
4
4
  * ✅ NO-LEGACY / ESTÁNDAR:
@@ -59,4 +59,33 @@ declare function requireRolesOrAnyPermission(roles: string[], perms: string[], o
59
59
  sysAdminRole?: string;
60
60
  }): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
61
61
 
62
- export { internalAuth, parseHeaders, requestId, requireAnyPermission, requireAuthContext, requirePermissions, requireRoles, requireRolesOrAnyPermission, sendError, sendOk };
62
+ /**
63
+ * ✅ SysAdmin bypass OR (ANY) permissions
64
+ * - Si tiene alguno de los permisos => OK
65
+ * - denied_permissions gana siempre
66
+ */
67
+ declare function allowSysAdminOrAnyPermission(...perms: string[]): RequestHandler[];
68
+ /**
69
+ * ✅ SysAdmin bypass OR (ALL) permissions (AND)
70
+ * - Debe tener TODOS los permisos requeridos
71
+ * - denied_permissions gana siempre
72
+ */
73
+ declare function allowSysAdminOrPermissionsAll(...perms: string[]): RequestHandler[];
74
+ /**
75
+ * ✅ SysAdmin bypass OR roles (ANY)
76
+ */
77
+ declare function allowSysAdminOrRoles(...roles: string[]): RequestHandler[];
78
+
79
+ /**
80
+ * ✅ SYS_ADMIN bypass OR (ANY) roles OR (ANY) permissions
81
+ * - parseHeaders + authEmployeeRequired incluidos
82
+ * - denied_permissions siempre gana
83
+ */
84
+ declare function allowSysAdminOrRolesOrAnyPermission(roles: string | string[], permissions: string | string[]): RequestHandler[];
85
+ /**
86
+ * ✅ Helper específico para el caso del Auth:
87
+ * Rol AUTH_ADMIN o permiso fino (y SYS_ADMIN bypass)
88
+ */
89
+ declare function allowAuthAdminOrPerm(permission: string): RequestHandler[];
90
+
91
+ export { allowAuthAdminOrPerm, allowSysAdminOrAnyPermission, allowSysAdminOrPermissionsAll, allowSysAdminOrRoles, allowSysAdminOrRolesOrAnyPermission, internalAuth, parseHeaders, requestId, requireAnyPermission, requireAuthContext, requirePermissions, requireRoles, requireRolesOrAnyPermission, sendError, sendOk };
@@ -1,4 +1,9 @@
1
1
  import {
2
+ allowAuthAdminOrPerm,
3
+ allowSysAdminOrAnyPermission,
4
+ allowSysAdminOrPermissionsAll,
5
+ allowSysAdminOrRoles,
6
+ allowSysAdminOrRolesOrAnyPermission,
2
7
  internalAuth,
3
8
  parseHeaders,
4
9
  requireAnyPermission,
@@ -8,12 +13,17 @@ import {
8
13
  requireRolesOrAnyPermission,
9
14
  sendError,
10
15
  sendOk
11
- } from "../chunk-JXOLNJ7J.js";
16
+ } from "../chunk-6E3X3D6Q.js";
12
17
  import {
13
18
  requestId
14
19
  } from "../chunk-KJ64O2EG.js";
15
20
  import "../chunk-P2U3MT2E.js";
16
21
  export {
22
+ allowAuthAdminOrPerm,
23
+ allowSysAdminOrAnyPermission,
24
+ allowSysAdminOrPermissionsAll,
25
+ allowSysAdminOrRoles,
26
+ allowSysAdminOrRolesOrAnyPermission,
17
27
  internalAuth,
18
28
  parseHeaders,
19
29
  requestId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@innvoid/getmarket-sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",