@innvoid/getmarket-sdk 0.1.5 → 0.1.8
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/chunk-JXOLNJ7J.js +224 -0
- package/dist/chunk-JXOLNJ7J.js.map +1 -0
- package/dist/chunk-KJ64O2EG.js +19 -0
- package/dist/{chunk-OJUNVATQ.js.map → chunk-KJ64O2EG.js.map} +1 -1
- package/dist/{chunk-RA5PN2F4.js → chunk-OSYBK5AN.js} +2 -2
- package/dist/chunk-P2U3MT2E.js +39 -0
- package/dist/chunk-P2U3MT2E.js.map +1 -0
- package/dist/core/index.js +2 -2
- package/dist/express.cjs.map +1 -1
- package/dist/express.d.cts +3 -0
- package/dist/express.d.ts +3 -0
- package/dist/headers/index.cjs +12 -6
- package/dist/headers/index.cjs.map +1 -1
- package/dist/headers/index.d.cts +1 -3
- package/dist/headers/index.d.ts +1 -3
- package/dist/headers/index.js +1 -1
- package/dist/index.cjs +401 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -4
- package/dist/index.d.ts +34 -4
- package/dist/index.js +305 -14
- package/dist/index.js.map +1 -1
- package/dist/middlewares/index.cjs +235 -136
- package/dist/middlewares/index.cjs.map +1 -1
- package/dist/middlewares/index.d.cts +51 -26
- package/dist/middlewares/index.d.ts +51 -26
- package/dist/middlewares/index.js +21 -17
- package/package.json +2 -2
- package/dist/chunk-65HACONF.js +0 -33
- package/dist/chunk-65HACONF.js.map +0 -1
- package/dist/chunk-A2E3FXYI.js +0 -157
- package/dist/chunk-A2E3FXYI.js.map +0 -1
- package/dist/chunk-OJUNVATQ.js +0 -11
- /package/dist/{chunk-RA5PN2F4.js.map → chunk-OSYBK5AN.js.map} +0 -0
|
@@ -1,37 +1,62 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
import { A as AuthContext, a as AuthMiddlewareOptions } from '../types-CRECQuHp.js';
|
|
3
|
-
export { b as AuthSession, c as AuthSubject, H as HydrateInput, d as HydrateResult, e as Hydrator, T as TokenType } from '../types-CRECQuHp.js';
|
|
4
|
-
import { JwtPayload } from 'jsonwebtoken';
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* ✅ NO-LEGACY / ESTÁNDAR:
|
|
5
|
+
* - Lee SOLO x-company y x-branch (UIDs planos)
|
|
6
|
+
* - Setea req.context = { company_uid, branch_uid }
|
|
7
|
+
* - NO toca req.auth (auth lo setea authentication/requireAuth)
|
|
8
|
+
*/
|
|
9
|
+
declare function parseHeaders(req: Request, _res: Response, next: NextFunction): void;
|
|
10
|
+
|
|
11
|
+
declare function requestId(req: Request, res: Response, next: NextFunction): void;
|
|
12
|
+
|
|
13
|
+
declare function internalAuth(req: Request, res: Response, next: NextFunction): void | Response<any, Record<string, any>>;
|
|
9
14
|
|
|
10
15
|
declare function sendOk<T>(_req: Request, res: Response, data: T, statusCode?: number): Response<any, Record<string, any>>;
|
|
11
16
|
declare function sendError(_req: Request, res: Response, statusCode: number, code: string, message: string, details?: any): Response<any, Record<string, any>>;
|
|
12
17
|
|
|
13
|
-
declare global {
|
|
14
|
-
namespace Express {
|
|
15
|
-
interface Request {
|
|
16
|
-
auth?: AuthContext;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
18
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* - Solo RS256
|
|
24
|
-
* - Cero legacy
|
|
25
|
-
* - Hidrata vía hook (OBLIGATORIO)
|
|
19
|
+
* 401 si no existe req.auth (contexto auth).
|
|
20
|
+
* Útil para proteger rutas donde SIEMPRE debe existir auth.
|
|
26
21
|
*/
|
|
27
|
-
declare function
|
|
28
|
-
|
|
22
|
+
declare function requireAuthContext(): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
23
|
+
/**
|
|
24
|
+
* Requiere TODOS los permisos indicados.
|
|
25
|
+
* Regla: denied_permissions siempre gana sobre permissions.
|
|
26
|
+
*
|
|
27
|
+
* options:
|
|
28
|
+
* - sysAdminBypass: default true
|
|
29
|
+
* - sysAdminRole: default "SYS_ADMIN"
|
|
30
|
+
*/
|
|
31
|
+
declare function requirePermissions(perms: string[], options?: {
|
|
32
|
+
sysAdminBypass?: boolean;
|
|
33
|
+
sysAdminRole?: string;
|
|
34
|
+
}): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
35
|
+
/**
|
|
36
|
+
* Requiere AL MENOS 1 permiso de la lista (ANY/OR).
|
|
37
|
+
* Regla: denied_permissions siempre gana.
|
|
38
|
+
*/
|
|
39
|
+
declare function requireAnyPermission(perms: string[], options?: {
|
|
40
|
+
sysAdminBypass?: boolean;
|
|
41
|
+
sysAdminRole?: string;
|
|
42
|
+
}): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
43
|
+
/**
|
|
44
|
+
* Requiere al menos 1 rol (ANY/OR).
|
|
45
|
+
* options:
|
|
46
|
+
* - sysAdminBypass: default true
|
|
47
|
+
* - sysAdminRole: default "SYS_ADMIN"
|
|
48
|
+
*/
|
|
49
|
+
declare function requireRoles(roles: string[], options?: {
|
|
50
|
+
sysAdminBypass?: boolean;
|
|
51
|
+
sysAdminRole?: string;
|
|
52
|
+
}): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
29
53
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* - fallback env AUTH_JWT_PUBLIC_KEY / AUTH_RSA_PUBLIC_KEY
|
|
54
|
+
* Requiere (roles ANY) OR (permissions ANY).
|
|
55
|
+
* deny_permissions siempre gana sobre permissions.
|
|
33
56
|
*/
|
|
34
|
-
declare function
|
|
35
|
-
|
|
57
|
+
declare function requireRolesOrAnyPermission(roles: string[], perms: string[], options?: {
|
|
58
|
+
sysAdminBypass?: boolean;
|
|
59
|
+
sysAdminRole?: string;
|
|
60
|
+
}): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
36
61
|
|
|
37
|
-
export {
|
|
62
|
+
export { internalAuth, parseHeaders, requestId, requireAnyPermission, requireAuthContext, requirePermissions, requireRoles, requireRolesOrAnyPermission, sendError, sendOk };
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
internalAuth,
|
|
3
|
+
parseHeaders,
|
|
4
|
+
requireAnyPermission,
|
|
5
|
+
requireAuthContext,
|
|
6
|
+
requirePermissions,
|
|
7
|
+
requireRoles,
|
|
8
|
+
requireRolesOrAnyPermission,
|
|
4
9
|
sendError,
|
|
5
|
-
sendOk
|
|
6
|
-
|
|
7
|
-
} from "../chunk-A2E3FXYI.js";
|
|
10
|
+
sendOk
|
|
11
|
+
} from "../chunk-JXOLNJ7J.js";
|
|
8
12
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from "../chunk-OJUNVATQ.js";
|
|
13
|
-
import "../chunk-65HACONF.js";
|
|
13
|
+
requestId
|
|
14
|
+
} from "../chunk-KJ64O2EG.js";
|
|
15
|
+
import "../chunk-P2U3MT2E.js";
|
|
14
16
|
export {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
internalAuth,
|
|
18
|
+
parseHeaders,
|
|
19
|
+
requestId,
|
|
20
|
+
requireAnyPermission,
|
|
21
|
+
requireAuthContext,
|
|
22
|
+
requirePermissions,
|
|
23
|
+
requireRoles,
|
|
24
|
+
requireRolesOrAnyPermission,
|
|
20
25
|
sendError,
|
|
21
|
-
sendOk
|
|
22
|
-
verifyBackendJwtRS256
|
|
26
|
+
sendOk
|
|
23
27
|
};
|
|
24
28
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@innvoid/getmarket-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@innvoid/getmarket-contracts": "^0.1.
|
|
75
|
+
"@innvoid/getmarket-contracts": "^0.1.5",
|
|
76
76
|
"axios": "^1.13.5",
|
|
77
77
|
"firebase-admin": "^13.6.1",
|
|
78
78
|
"jsonwebtoken": "^9.0.2",
|
package/dist/chunk-65HACONF.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// src/headers/constants.ts
|
|
2
|
-
var HEADER_REQUEST_ID = "x-request-id";
|
|
3
|
-
var HEADER_COMPANY_UID = "x-company";
|
|
4
|
-
var HEADER_BRANCH_UID = "x-branch";
|
|
5
|
-
var HEADER_EMPLOYEE_UID = "x-employee-uid";
|
|
6
|
-
var HEADER_INTERNAL_API_KEY = "x-internal-api-key";
|
|
7
|
-
var HEADER_AUTHORIZATION = "authorization";
|
|
8
|
-
|
|
9
|
-
// src/headers/parse.ts
|
|
10
|
-
function asString(v) {
|
|
11
|
-
if (typeof v !== "string") return null;
|
|
12
|
-
const s = v.trim();
|
|
13
|
-
return s ? s : null;
|
|
14
|
-
}
|
|
15
|
-
function getRequestContextFromHeaders(headers) {
|
|
16
|
-
return {
|
|
17
|
-
requestId: asString(headers[HEADER_REQUEST_ID]) ?? null,
|
|
18
|
-
company_uid: asString(headers[HEADER_COMPANY_UID]) ?? null,
|
|
19
|
-
branch_uid: asString(headers[HEADER_BRANCH_UID]) ?? null,
|
|
20
|
-
employee_uid: asString(headers[HEADER_EMPLOYEE_UID]) ?? null
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
HEADER_REQUEST_ID,
|
|
26
|
-
HEADER_COMPANY_UID,
|
|
27
|
-
HEADER_BRANCH_UID,
|
|
28
|
-
HEADER_EMPLOYEE_UID,
|
|
29
|
-
HEADER_INTERNAL_API_KEY,
|
|
30
|
-
HEADER_AUTHORIZATION,
|
|
31
|
-
getRequestContextFromHeaders
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=chunk-65HACONF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/headers/constants.ts","../src/headers/parse.ts"],"sourcesContent":["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\n company_uid?: string | null;\n branch_uid?: string | null;\n employee_uid?: string | null;\n};\n\nfunction asString(v: unknown): string | null {\n if (typeof v !== \"string\") return null;\n const s = v.trim();\n return s ? s : null;\n}\n\n/**\n * ✅ NO-LEGACY:\n * - x-company: <UID>\n * - x-branch: <UID>\n * - x-employee-uid: <UID> (opcional)\n * - x-request-id: string (opcional)\n *\n * 🚫 No JSON, no _id, no objetos.\n */\nexport function getRequestContextFromHeaders(headers: Record<string, any>): RequestContext {\n return {\n requestId: asString(headers[HEADER_REQUEST_ID]) ?? null,\n company_uid: asString(headers[HEADER_COMPANY_UID]) ?? null,\n branch_uid: asString(headers[HEADER_BRANCH_UID]) ?? null,\n employee_uid: asString(headers[HEADER_EMPLOYEE_UID]) ?? null,\n };\n}\n"],"mappings":";AAAO,IAAM,oBAAoB;AAE1B,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAE5B,IAAM,0BAA0B;AAChC,IAAM,uBAAuB;;;ACQpC,SAAS,SAAS,GAA2B;AACzC,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,IAAI,EAAE,KAAK;AACjB,SAAO,IAAI,IAAI;AACnB;AAWO,SAAS,6BAA6B,SAA8C;AACvF,SAAO;AAAA,IACH,WAAW,SAAS,QAAQ,iBAAiB,CAAC,KAAK;AAAA,IACnD,aAAa,SAAS,QAAQ,kBAAkB,CAAC,KAAK;AAAA,IACtD,YAAY,SAAS,QAAQ,iBAAiB,CAAC,KAAK;AAAA,IACpD,cAAc,SAAS,QAAQ,mBAAmB,CAAC,KAAK;AAAA,EAC5D;AACJ;","names":[]}
|
package/dist/chunk-A2E3FXYI.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
// src/middlewares/respond.ts
|
|
2
|
-
function sendOk(_req, res, data, statusCode = 200) {
|
|
3
|
-
return res.status(statusCode).json({ ok: true, data, requestId: res.locals?.requestId ?? null });
|
|
4
|
-
}
|
|
5
|
-
function sendError(_req, res, statusCode, code, message, details) {
|
|
6
|
-
return res.status(statusCode).json({
|
|
7
|
-
ok: false,
|
|
8
|
-
error: { code, message, ...details !== void 0 ? { details } : {} },
|
|
9
|
-
requestId: res.locals?.requestId ?? null
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// src/auth/jwt.ts
|
|
14
|
-
import fs from "fs";
|
|
15
|
-
import jwt from "jsonwebtoken";
|
|
16
|
-
function readFileIfExists(path) {
|
|
17
|
-
if (!path) return null;
|
|
18
|
-
try {
|
|
19
|
-
const v = fs.readFileSync(path, "utf8").trim();
|
|
20
|
-
return v.length ? v : null;
|
|
21
|
-
} catch {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function readRs256PublicKey() {
|
|
26
|
-
const fromFile = readFileIfExists(process.env.JWT_PUBLIC_KEY_PATH);
|
|
27
|
-
if (fromFile) return fromFile;
|
|
28
|
-
const fromEnv = String(process.env.AUTH_JWT_PUBLIC_KEY || process.env.AUTH_RSA_PUBLIC_KEY || "").replace(/\\n/g, "\n").trim();
|
|
29
|
-
if (fromEnv) return fromEnv;
|
|
30
|
-
throw new Error("Missing RS256 public key (JWT_PUBLIC_KEY_PATH / AUTH_JWT_PUBLIC_KEY / AUTH_RSA_PUBLIC_KEY)");
|
|
31
|
-
}
|
|
32
|
-
function verifyBackendJwtRS256(raw) {
|
|
33
|
-
const publicKey = readRs256PublicKey();
|
|
34
|
-
const audience = process.env.JWT_AUDIENCE || process.env.AUTH_JWT_AUDIENCE || "getmarket.api";
|
|
35
|
-
const issuer = process.env.JWT_ISSUER || process.env.AUTH_JWT_ISSUER || "getmarket-auth";
|
|
36
|
-
return jwt.verify(raw, publicKey, {
|
|
37
|
-
algorithms: ["RS256"],
|
|
38
|
-
audience,
|
|
39
|
-
issuer
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// src/auth/middleware.ts
|
|
44
|
-
function getBearerToken(req) {
|
|
45
|
-
const auth = String(req.headers?.authorization || "");
|
|
46
|
-
if (!auth.startsWith("Bearer ")) return null;
|
|
47
|
-
const token = auth.slice(7).trim();
|
|
48
|
-
return token.length ? token : null;
|
|
49
|
-
}
|
|
50
|
-
function normalizeUid(v) {
|
|
51
|
-
const s = String(v ?? "").trim();
|
|
52
|
-
return s.length ? s : null;
|
|
53
|
-
}
|
|
54
|
-
function createAuthMiddleware(opts) {
|
|
55
|
-
const {
|
|
56
|
-
subject,
|
|
57
|
-
allowFirebaseIdToken = false,
|
|
58
|
-
requireSubject = true,
|
|
59
|
-
hydrate
|
|
60
|
-
} = opts;
|
|
61
|
-
return async (req, res, next) => {
|
|
62
|
-
const token = getBearerToken(req);
|
|
63
|
-
if (!token) {
|
|
64
|
-
return res.status(401).json({
|
|
65
|
-
ok: false,
|
|
66
|
-
code: "AUTH_MISSING_TOKEN",
|
|
67
|
-
message: "Missing Authorization Bearer token"
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
const headerCtx = req.context || {};
|
|
71
|
-
const company_uid = normalizeUid(headerCtx.company_uid);
|
|
72
|
-
const branch_uid = normalizeUid(headerCtx.branch_uid);
|
|
73
|
-
try {
|
|
74
|
-
const decoded = verifyBackendJwtRS256(token);
|
|
75
|
-
const baseCtx = {
|
|
76
|
-
tokenType: "backend",
|
|
77
|
-
subject,
|
|
78
|
-
company_uid: company_uid ?? void 0,
|
|
79
|
-
branch_uid: branch_uid ?? void 0,
|
|
80
|
-
roles: Array.isArray(decoded?.roles) ? decoded.roles : [],
|
|
81
|
-
permissions: Array.isArray(decoded?.permissions) ? decoded.permissions : [],
|
|
82
|
-
denied_permissions: Array.isArray(decoded?.denied_permissions) ? decoded.denied_permissions : [],
|
|
83
|
-
session: {
|
|
84
|
-
jti: decoded?.jti,
|
|
85
|
-
device_id: decoded?.device_id,
|
|
86
|
-
expires_at: decoded?.exp
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
const hydrated = await hydrate({ decoded, req, subject, company_uid, branch_uid });
|
|
90
|
-
Object.assign(baseCtx, hydrated);
|
|
91
|
-
if (requireSubject) {
|
|
92
|
-
if (subject === "employee" && !baseCtx.employee) {
|
|
93
|
-
return res.status(401).json({
|
|
94
|
-
ok: false,
|
|
95
|
-
code: "AUTH_EMPLOYEE_NOT_FOUND",
|
|
96
|
-
message: "Employee not resolved by hydrator"
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
if (subject === "customer" && !baseCtx.customer) {
|
|
100
|
-
return res.status(401).json({
|
|
101
|
-
ok: false,
|
|
102
|
-
code: "AUTH_CUSTOMER_NOT_FOUND",
|
|
103
|
-
message: "Customer not resolved by hydrator"
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
req.auth = baseCtx;
|
|
108
|
-
return next();
|
|
109
|
-
} catch {
|
|
110
|
-
if (!allowFirebaseIdToken) {
|
|
111
|
-
return res.status(401).json({
|
|
112
|
-
ok: false,
|
|
113
|
-
code: "AUTH_INVALID_TOKEN",
|
|
114
|
-
message: "Invalid or expired token"
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
const { default: admin } = await import("firebase-admin");
|
|
119
|
-
const firebaseDecoded = await admin.auth().verifyIdToken(token);
|
|
120
|
-
if (firebaseDecoded.email && firebaseDecoded.email_verified === false) {
|
|
121
|
-
return res.status(401).json({
|
|
122
|
-
ok: false,
|
|
123
|
-
code: "AUTH_EMAIL_NOT_VERIFIED",
|
|
124
|
-
message: "Email not verified"
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
req.auth = {
|
|
128
|
-
tokenType: "backend",
|
|
129
|
-
subject,
|
|
130
|
-
firebase: firebaseDecoded,
|
|
131
|
-
company_uid: company_uid ?? void 0,
|
|
132
|
-
branch_uid: branch_uid ?? void 0,
|
|
133
|
-
companies: [],
|
|
134
|
-
roles: [],
|
|
135
|
-
permissions: [],
|
|
136
|
-
denied_permissions: []
|
|
137
|
-
};
|
|
138
|
-
return next();
|
|
139
|
-
} catch {
|
|
140
|
-
return res.status(401).json({
|
|
141
|
-
ok: false,
|
|
142
|
-
code: "AUTH_INVALID_TOKEN",
|
|
143
|
-
message: "Invalid or expired token"
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export {
|
|
151
|
-
sendOk,
|
|
152
|
-
sendError,
|
|
153
|
-
readRs256PublicKey,
|
|
154
|
-
verifyBackendJwtRS256,
|
|
155
|
-
createAuthMiddleware
|
|
156
|
-
};
|
|
157
|
-
//# sourceMappingURL=chunk-A2E3FXYI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/middlewares/respond.ts","../src/auth/jwt.ts","../src/auth/middleware.ts"],"sourcesContent":["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","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","import type {NextFunction, Response} from \"express\";\nimport {verifyBackendJwtRS256} from \"./jwt\";\nimport type {AuthContext, AuthMiddlewareOptions} from \"./types\";\n\ndeclare global {\n namespace Express {\n interface Request {\n auth?: AuthContext;\n }\n }\n}\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 normalizeUid(v: any): string | null {\n const s = String(v ?? \"\").trim();\n return s.length ? s : null;\n}\n\n/**\n * ✅ Middleware estándar:\n * - Solo Authorization: Bearer\n * - Solo RS256\n * - Cero legacy\n * - Hidrata vía hook (OBLIGATORIO)\n */\nexport function createAuthMiddleware(opts: AuthMiddlewareOptions) {\n const {\n subject,\n allowFirebaseIdToken = false,\n requireSubject = true,\n hydrate,\n } = 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 // Contexto desde parseHeaders (SDK) -> req.context\n const headerCtx = (req as any).context || {};\n const company_uid = normalizeUid(headerCtx.company_uid);\n const branch_uid = normalizeUid(headerCtx.branch_uid);\n\n // 1) RS256 backend JWT\n try {\n const decoded: any = verifyBackendJwtRS256(token);\n\n const baseCtx: AuthContext = {\n tokenType: \"backend\",\n subject,\n company_uid: company_uid ?? undefined,\n branch_uid: branch_uid ?? undefined,\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 session: {\n jti: decoded?.jti,\n device_id: decoded?.device_id,\n expires_at: decoded?.exp,\n },\n };\n\n // ✅ hydrate obligatorio (cero legacy)\n const hydrated = await hydrate({decoded, req, subject, company_uid, branch_uid});\n Object.assign(baseCtx, hydrated);\n\n if (requireSubject) {\n if (subject === \"employee\" && !baseCtx.employee) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_EMPLOYEE_NOT_FOUND\",\n message: \"Employee not resolved by hydrator\",\n });\n }\n if (subject === \"customer\" && !baseCtx.customer) {\n return res.status(401).json({\n ok: false,\n code: \"AUTH_CUSTOMER_NOT_FOUND\",\n message: \"Customer not resolved by hydrator\",\n });\n }\n }\n\n req.auth = baseCtx;\n return next();\n } catch {\n // 2) Firebase opcional (si está habilitado explícitamente)\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 {default: admin} = await import(\"firebase-admin\");\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 req.auth = {\n tokenType: \"backend\",\n subject,\n firebase: firebaseDecoded,\n company_uid: company_uid ?? undefined,\n branch_uid: branch_uid ?? 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"],"mappings":"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","names":[]}
|
package/dist/chunk-OJUNVATQ.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// src/middlewares/requestId.ts
|
|
2
|
-
var REQUEST_ID_HEADER = "x-request-id";
|
|
3
|
-
var REQUEST_ID_HEADER_ALT = "x-requestid";
|
|
4
|
-
var RESPONSE_REQUEST_ID_HEADER = "X-Request-Id";
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
REQUEST_ID_HEADER,
|
|
8
|
-
REQUEST_ID_HEADER_ALT,
|
|
9
|
-
RESPONSE_REQUEST_ID_HEADER
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=chunk-OJUNVATQ.js.map
|
|
File without changes
|