@plasius/api
Advanced tools
| export * from "./withMiddleware.js"; | ||
| export * from "./withMCPHeader.js"; | ||
| export * from "./withCors.js"; | ||
| export * from "./withRateLimiting.js"; | ||
| export * from "./withLogging.js"; | ||
| export * from "./withSession.js"; | ||
| export * from "./withCSRF.js"; | ||
| export * from "./withSecurity.js"; | ||
| export * from "./withDefaultMiddleware.js"; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC"} |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./withMiddleware.js"), exports); | ||
| __exportStar(require("./withMCPHeader.js"), exports); | ||
| __exportStar(require("./withCors.js"), exports); | ||
| __exportStar(require("./withRateLimiting.js"), exports); | ||
| __exportStar(require("./withLogging.js"), exports); | ||
| __exportStar(require("./withSession.js"), exports); | ||
| __exportStar(require("./withCSRF.js"), exports); | ||
| __exportStar(require("./withSecurity.js"), exports); | ||
| __exportStar(require("./withDefaultMiddleware.js"), exports); | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,qDAAmC;AACnC,gDAA8B;AAC9B,wDAAsC;AACtC,mDAAiC;AACjC,mDAAiC;AACjC,gDAA8B;AAC9B,oDAAkC;AAClC,6DAA2C"} |
| import { Middleware } from "./withMiddleware.js"; | ||
| export declare function withCors(allowedOrigins?: string[], allowedMethods?: string[], allowedHeaders?: string[]): Middleware; | ||
| //# sourceMappingURL=withCors.d.ts.map |
| {"version":3,"file":"withCors.d.ts","sourceRoot":"","sources":["../../src/middleware/withCors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,wBAAgB,QAAQ,CACtB,cAAc,GAAE,MAAM,EAAU,EAChC,cAAc,GAAE,MAAM,EAQrB,EACD,cAAc,GAAE,MAAM,EAAsC,GAC3D,UAAU,CA0CZ"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withCors = withCors; | ||
| const index_js_1 = require("../utils/index.js"); | ||
| function withCors(allowedOrigins = ["*"], allowedMethods = [ | ||
| "GET", | ||
| "POST", | ||
| "PUT", | ||
| "PATCH", | ||
| "DELETE", | ||
| "OPTIONS", | ||
| "HEAD", | ||
| ], allowedHeaders = ["Content-Type", "Authorization"]) { | ||
| return async (req, context) => { | ||
| const logger = context.extraInputs.get("logger"); | ||
| const { headers, cookies } = (0, index_js_1.getExtraOutputs)(context); | ||
| logger?.log(`[withCors] Executing middleware for ${req.method} ${req.url}`); | ||
| const origin = req.headers.get("origin") ?? "*"; | ||
| const isOriginAllowed = allowedOrigins.includes("*") || allowedOrigins.includes(origin); | ||
| if (!isOriginAllowed) { | ||
| logger?.warn(`CORS blocked request from origin: ${origin}`); | ||
| } | ||
| headers.set("Access-Control-Allow-Origin", isOriginAllowed ? origin : "null"); | ||
| headers.set("Access-Control-Allow-Methods", allowedMethods.join(", ")); | ||
| headers.set("Access-Control-Allow-Headers", allowedHeaders.join(", ")); | ||
| headers.set("Access-Control-Allow-Credentials", "true"); | ||
| headers.set("Referrer-Policy", "origin-when-cross-origin"); | ||
| context.extraOutputs.set("headers", headers); | ||
| if (req.method === "OPTIONS") { | ||
| logger?.log("CORS preflight request received. Returning early with 204."); | ||
| context.extraOutputs.set("http", { | ||
| status: 204, | ||
| headers, | ||
| cookies, | ||
| }); | ||
| return false; | ||
| } | ||
| return true; | ||
| }; | ||
| } | ||
| //# sourceMappingURL=withCors.js.map |
| {"version":3,"file":"withCors.js","sourceRoot":"","sources":["../../src/middleware/withCors.ts"],"names":[],"mappings":";;AAIA,4BAsDC;AAxDD,gDAAoD;AAEpD,SAAgB,QAAQ,CACtB,iBAA2B,CAAC,GAAG,CAAC,EAChC,iBAA2B;IACzB,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,SAAS;IACT,MAAM;CACP,EACD,iBAA2B,CAAC,cAAc,EAAE,eAAe,CAAC;IAE5D,OAAO,KAAK,EAAE,GAAgB,EAAE,OAA0B,EAAE,EAAE;QAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAI9C,CAAC;QAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;QACtD,MAAM,EAAE,GAAG,CAAC,uCAAuC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAE5E,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;QAChD,MAAM,eAAe,GACnB,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAElE,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,EAAE,IAAI,CAAC,qCAAqC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,CAAC,GAAG,CACT,6BAA6B,EAC7B,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAClC,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,0BAA0B,CAAC,CAAC;QAE3D,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE7C,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,EAAE,GAAG,CAAC,4DAA4D,CAAC,CAAC;YAC1E,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE;gBAC/B,MAAM,EAAE,GAAG;gBACX,OAAO;gBACP,OAAO;aACR,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"} |
| import type { Middleware } from "./withMiddleware"; | ||
| export declare const withCSRF: () => Middleware; | ||
| //# sourceMappingURL=withCSRF.d.ts.map |
| {"version":3,"file":"withCSRF.d.ts","sourceRoot":"","sources":["../../src/middleware/withCSRF.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD,eAAO,MAAM,QAAQ,QAAO,UAoD3B,CAAC"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withCSRF = void 0; | ||
| const utils_1 = require("../utils"); | ||
| const crypto_1 = require("crypto"); | ||
| const index_js_1 = require("../utils/index.js"); | ||
| const CSRF_HEADER_NAME = "x-csrf-token"; | ||
| const CSRF_COOKIE_NAME = "csrf-token"; | ||
| const withCSRF = () => { | ||
| return async (request, context) => { | ||
| const logger = context.extraInputs.get("logger"); | ||
| const { headers, cookies } = (0, index_js_1.getExtraOutputs)(context); | ||
| const method = request.method?.toUpperCase(); | ||
| const isReadOnly = method === "GET" || method === "HEAD" || method === "OPTIONS"; | ||
| // Read token from header and cookie | ||
| const headerToken = request.headers?.get(CSRF_HEADER_NAME); | ||
| const cookieToken = (0, utils_1.getCookie)(request, CSRF_COOKIE_NAME); | ||
| // ✅ If GET and no CSRF cookie set, generate one | ||
| if (isReadOnly && !cookieToken) { | ||
| const newToken = (0, crypto_1.randomUUID)(); | ||
| const newCookies = [ | ||
| ...cookies, | ||
| { | ||
| name: CSRF_COOKIE_NAME, | ||
| value: newToken, | ||
| secure: true, | ||
| sameSite: "None", | ||
| path: "/", | ||
| maxAge: 10 * 60, // 10 minutes | ||
| }, | ||
| ]; | ||
| context.extraOutputs.set("cookies", newCookies); | ||
| logger.log("CSRF token set on GET request"); | ||
| } | ||
| // Only validate CSRF token on non-readonly methods | ||
| if (!isReadOnly) { | ||
| if (!headerToken || !cookieToken || headerToken !== cookieToken) { | ||
| logger.warn("CSRF token validation failed."); | ||
| context.extraOutputs.set("http", { | ||
| status: 403, | ||
| headers, | ||
| cookies, | ||
| body: "Invalid CSRF token.", | ||
| }); | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| }; | ||
| }; | ||
| exports.withCSRF = withCSRF; | ||
| //# sourceMappingURL=withCSRF.js.map |
| {"version":3,"file":"withCSRF.js","sourceRoot":"","sources":["../../src/middleware/withCSRF.ts"],"names":[],"mappings":";;;AAEA,oCAAqC;AACrC,mCAAoC;AACpC,gDAAoD;AAEpD,MAAM,gBAAgB,GAAG,cAAc,CAAC;AACxC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE/B,MAAM,QAAQ,GAAG,GAAe,EAAE;IACvC,OAAO,KAAK,EAAE,OAAoB,EAAE,OAA0B,EAAE,EAAE;QAChE,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAI9C,CAAC;QAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;QAC7C,MAAM,UAAU,GACd,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,SAAS,CAAC;QAEhE,oCAAoC;QACpC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3D,MAAM,WAAW,GAAG,IAAA,iBAAS,EAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAEzD,gDAAgD;QAChD,IAAI,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAA,mBAAU,GAAE,CAAC;YAC9B,MAAM,UAAU,GAAG;gBACjB,GAAG,OAAO;gBACV;oBACE,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,QAAQ;oBACf,MAAM,EAAE,IAAI;oBACZ,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,GAAG;oBACT,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,aAAa;iBAC/B;aACF,CAAC;YAEF,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC9C,CAAC;QAED,mDAAmD;QACnD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;gBAChE,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;gBAC7C,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE;oBAC/B,MAAM,EAAE,GAAG;oBACX,OAAO;oBACP,OAAO;oBACP,IAAI,EAAE,qBAAqB;iBAC5B,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC,CAAC;AApDW,QAAA,QAAQ,YAoDnB"} |
| import type { Middleware } from "./withMiddleware.js"; | ||
| export declare function withDefaultMiddleware(): Middleware[]; | ||
| //# sourceMappingURL=withDefaultMiddleware.d.ts.map |
| {"version":3,"file":"withDefaultMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/withDefaultMiddleware.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD,wBAAgB,qBAAqB,IAAI,UAAU,EAAE,CAmCpD"} |
| "use strict"; | ||
| // backend/src/middleware/defaultMiddleware.ts | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withDefaultMiddleware = withDefaultMiddleware; | ||
| const withCors_1 = require("./withCors"); | ||
| const withSecurity_1 = require("./withSecurity"); | ||
| const withRateLimiting_1 = require("./withRateLimiting"); | ||
| const withCSRF_1 = require("./withCSRF"); | ||
| const withSession_1 = require("./withSession"); | ||
| function withDefaultMiddleware() { | ||
| return [ | ||
| (0, withCSRF_1.withCSRF)(), | ||
| (0, withSecurity_1.withSecurity)(), | ||
| (0, withCors_1.withCors)([ | ||
| "*", | ||
| ], ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], [ | ||
| "Content-Type", | ||
| "Authorization", | ||
| "x-csrf-token", | ||
| "x-requested-with", | ||
| "Accept", | ||
| "Cookie", | ||
| "Set-Cookie", | ||
| "Origin", | ||
| "Referer", | ||
| "X-Forwarded-For", | ||
| "X-Real-IP", | ||
| "X-Session-Id", | ||
| "Cache-Control", | ||
| "Pragma", | ||
| "If-None-Match", | ||
| "ETag", | ||
| ]), | ||
| (0, withRateLimiting_1.withRateLimiting)({ | ||
| global: { limit: 1000, windowMs: 60 * 1000 }, // 1000 requests per minute | ||
| perUser: { limit: 10, windowMs: 60 * 1000 }, // 100 requests per user per minute | ||
| perApi: { limit: 500, windowMs: 60 * 1000 }, // 500 requests per API endpoint per minute | ||
| }), | ||
| withSession_1.withSession, | ||
| ]; | ||
| } | ||
| //# sourceMappingURL=withDefaultMiddleware.js.map |
| {"version":3,"file":"withDefaultMiddleware.js","sourceRoot":"","sources":["../../src/middleware/withDefaultMiddleware.ts"],"names":[],"mappings":";AAAA,8CAA8C;;AAS9C,sDAmCC;AA1CD,yCAAsC;AACtC,iDAA8C;AAC9C,yDAAsD;AAEtD,yCAAsC;AACtC,+CAA4C;AAE5C,SAAgB,qBAAqB;IACnC,OAAO;QACL,IAAA,mBAAQ,GAAE;QACV,IAAA,2BAAY,GAAE;QACd,IAAA,mBAAQ,EACN;YACE,GAAG;SACJ,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,EACpD;YACE,cAAc;YACd,eAAe;YACf,cAAc;YACd,kBAAkB;YAClB,QAAQ;YACR,QAAQ;YACR,YAAY;YACZ,QAAQ;YACR,SAAS;YACT,iBAAiB;YACjB,WAAW;YACX,cAAc;YACd,eAAe;YACf,QAAQ;YACR,eAAe;YACf,MAAM;SACP,CACF;QACD,IAAA,mCAAgB,EAAC;YACf,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,2BAA2B;YACzE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,mCAAmC;YAChF,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,2CAA2C;SACzF,CAAC;QACF,yBAAW;KACZ,CAAC;AACJ,CAAC"} |
| import { Middleware } from "./withMiddleware.js"; | ||
| export declare const withLogging: Middleware; | ||
| //# sourceMappingURL=withLogging.d.ts.map |
| {"version":3,"file":"withLogging.d.ts","sourceRoot":"","sources":["../../src/middleware/withLogging.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,eAAO,MAAM,WAAW,EAAE,UA6BzB,CAAC"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withLogging = void 0; | ||
| const withLogging = async (req, context) => { | ||
| const method = req.method; | ||
| const path = req.url; | ||
| const prefix = `${method} ${path} `; | ||
| function makeLogger(context) { | ||
| return { | ||
| log: (...args) => context.log(...args.map((arg) => (typeof arg === "string" ? prefix + arg : arg))), | ||
| warn: (...args) => context.warn(...args.map((arg) => (typeof arg === "string" ? prefix + arg : arg))), | ||
| error: (...args) => context.error(...args.map((arg) => (typeof arg === "string" ? prefix + arg : arg))), | ||
| }; | ||
| } | ||
| context.extraInputs.set("logger", makeLogger(context)); | ||
| return true; | ||
| }; | ||
| exports.withLogging = withLogging; | ||
| //# sourceMappingURL=withLogging.js.map |
| {"version":3,"file":"withLogging.js","sourceRoot":"","sources":["../../src/middleware/withLogging.ts"],"names":[],"mappings":";;;AAGO,MAAM,WAAW,GAAe,KAAK,EAC1C,GAAgB,EAChB,OAA0B,EAC1B,EAAE;IACF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;IAErB,MAAM,MAAM,GAAG,GAAG,MAAM,IAAI,IAAI,GAAG,CAAC;IAEpC,SAAS,UAAU,CAAC,OAA0B;QAC5C,OAAO;YACL,GAAG,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CACtB,OAAO,CAAC,GAAG,CACT,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CACrE;YACH,IAAI,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CACvB,OAAO,CAAC,IAAI,CACV,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CACrE;YACH,KAAK,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CACxB,OAAO,CAAC,KAAK,CACX,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CACrE;SACJ,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAEvD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AA7BW,QAAA,WAAW,eA6BtB"} |
| import { Middleware } from "./withMiddleware.js"; | ||
| export declare const withMCPHeader: Middleware; | ||
| //# sourceMappingURL=withMCPHeader.d.ts.map |
| {"version":3,"file":"withMCPHeader.d.ts","sourceRoot":"","sources":["../../src/middleware/withMCPHeader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,UAc3B,CAAC"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withMCPHeader = void 0; | ||
| const withMCPHeader = async (req, context) => { | ||
| const modelHeader = req.headers.get("x-mcp-model"); | ||
| if (!modelHeader) { | ||
| context.extraOutputs.set("response", { | ||
| status: 400, | ||
| body: { error: "Missing x-mcp-model header" }, | ||
| }); | ||
| return false; | ||
| } | ||
| // Could add more validation or parsing here | ||
| return true; | ||
| }; | ||
| exports.withMCPHeader = withMCPHeader; | ||
| //# sourceMappingURL=withMCPHeader.js.map |
| {"version":3,"file":"withMCPHeader.js","sourceRoot":"","sources":["../../src/middleware/withMCPHeader.ts"],"names":[],"mappings":";;;AAGO,MAAM,aAAa,GAAe,KAAK,EAC5C,GAAgB,EAChB,OAA0B,EAC1B,EAAE;IACF,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE;YACnC,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE;SAC9C,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC;IACD,4CAA4C;IAC5C,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAdW,QAAA,aAAa,iBAcxB"} |
| import type { HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; | ||
| export type AzureFunction = (req: HttpRequest, context: InvocationContext) => Promise<HttpResponseInit>; | ||
| export type Middleware = (req: HttpRequest, context: InvocationContext) => Promise<boolean>; | ||
| export declare function withMiddleware(handler: AzureFunction, middlewares: Middleware[]): AzureFunction; | ||
| //# sourceMappingURL=withMiddleware.d.ts.map |
| {"version":3,"file":"withMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/withMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AASzF,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,iBAAiB,KACvB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,iBAAiB,KACvB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,UAAU,EAAE,GACxB,aAAa,CAuDf"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withMiddleware = withMiddleware; | ||
| const withLogging_1 = require("./withLogging"); | ||
| const index_js_1 = require("../utils/index.js"); | ||
| const transportSecurity_js_1 = require("./transportSecurity.js"); | ||
| function withMiddleware(handler, middlewares) { | ||
| return async function (req, context) { | ||
| context.extraInputs.set("fetchData", handler); | ||
| const start = Date.now(); | ||
| const ip = (0, index_js_1.extractAndHashClientIp)(req); | ||
| const userAgent = req.headers.get("user-agent") ?? "unknown"; | ||
| const method = req.method; | ||
| const path = req.url; | ||
| // Add additional logging context to all context.log/.warn/.error messages | ||
| await (0, withLogging_1.withLogging)(req, context); | ||
| const { headers, cookies } = (0, index_js_1.getExtraOutputs)(context); | ||
| (0, transportSecurity_js_1.applyBaselineSecurityHeaders)(headers); | ||
| context.extraOutputs.set("headers", headers); | ||
| if ((0, transportSecurity_js_1.shouldEnforceHttps)() && | ||
| !(0, transportSecurity_js_1.isHttpsRequest)(req) && | ||
| !(0, transportSecurity_js_1.isInsecureLocalRequest)(req)) { | ||
| context.log("request rejected: insecure transport in https-enforced mode"); | ||
| return { | ||
| status: 426, | ||
| headers, | ||
| cookies, | ||
| body: "HTTPS is required.", | ||
| }; | ||
| } | ||
| for (const mw of middlewares) { | ||
| const continueProcessing = await mw(req, context); | ||
| if (!continueProcessing) { | ||
| // Middleware handled response or aborted | ||
| return context.extraOutputs.get("http"); | ||
| } | ||
| } | ||
| const value = await handler(req, context); | ||
| const end = Date.now(); | ||
| const duration = end - start; | ||
| context.log(`Handled ${method} ${path} | IP: ${ip} | Agent: ${userAgent} | Duration: ${duration}ms`); | ||
| return value; | ||
| }; | ||
| } | ||
| //# sourceMappingURL=withMiddleware.js.map |
| {"version":3,"file":"withMiddleware.js","sourceRoot":"","sources":["../../src/middleware/withMiddleware.ts"],"names":[],"mappings":";;AAmBA,wCA0DC;AA5ED,+CAA4C;AAC5C,gDAA4E;AAC5E,iEAKgC;AAWhC,SAAgB,cAAc,CAC5B,OAAsB,EACtB,WAAyB;IAEzB,OAAO,KAAK,WACV,GAAgB,EAChB,OAA0B;QAE1B,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,MAAM,EAAE,GAAG,IAAA,iCAAsB,EAAC,GAAG,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC;QAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;QAErB,0EAA0E;QAC1E,MAAM,IAAA,yBAAW,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEhC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;QACtD,IAAA,mDAA4B,EAAC,OAAO,CAAC,CAAC;QACtC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE7C,IACE,IAAA,yCAAkB,GAAE;YACpB,CAAC,IAAA,qCAAc,EAAC,GAAG,CAAC;YACpB,CAAC,IAAA,6CAAsB,EAAC,GAAG,CAAC,EAC5B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;YAC3E,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,OAAO;gBACP,OAAO;gBACP,IAAI,EAAE,oBAAoB;aAC3B,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,MAAM,kBAAkB,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAClD,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,yCAAyC;gBAEzC,OAAO,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAqB,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,GAAG,GAAG,KAAK,CAAC;QAE7B,OAAO,CAAC,GAAG,CACT,WAAW,MAAM,IAAI,IAAI,UAAU,EAAE,aAAa,SAAS,gBAAgB,QAAQ,IAAI,CACxF,CAAC;QAEF,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"} |
| import { Middleware } from "./withMiddleware.js"; | ||
| export interface RateLimitConfig { | ||
| limit: number; | ||
| windowMs: number; | ||
| } | ||
| export interface ApiRateLimiterConfig { | ||
| global?: RateLimitConfig; | ||
| perUser?: RateLimitConfig; | ||
| perApi?: RateLimitConfig; | ||
| } | ||
| export declare function withRateLimiting(config: ApiRateLimiterConfig): Middleware; | ||
| //# sourceMappingURL=withRateLimiting.d.ts.map |
| {"version":3,"file":"withRateLimiting.d.ts","sourceRoot":"","sources":["../../src/middleware/withRateLimiting.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAuFD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,GAAG,UAAU,CA+EzE"} |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withRateLimiting = withRateLimiting; | ||
| const ioredis_1 = __importDefault(require("ioredis")); | ||
| const redisUrl = process.env.REDIS_URL?.trim(); | ||
| const redisHost = process.env.REDIS_HOST?.trim(); | ||
| const redisEnabled = (process.env.REDIS_ENABLED ?? | ||
| ((redisUrl || redisHost) ? "true" : "false")).toLowerCase() === "true"; | ||
| let redisClient; | ||
| function getRedisClient() { | ||
| if (!redisEnabled) { | ||
| return null; | ||
| } | ||
| if (redisClient !== undefined) { | ||
| return redisClient; | ||
| } | ||
| redisClient = redisUrl | ||
| ? new ioredis_1.default(redisUrl, { lazyConnect: true }) | ||
| : new ioredis_1.default({ | ||
| host: redisHost ?? "redis", | ||
| port: Number(process.env.REDIS_PORT ?? 6379), | ||
| password: process.env.REDIS_PASSWORD, | ||
| lazyConnect: true, | ||
| }); | ||
| return redisClient; | ||
| } | ||
| async function checkRateLimit(key, config, context) { | ||
| const logger = context.extraInputs.get("logger"); | ||
| const now = Date.now(); | ||
| const windowKey = `${key}:${Math.floor(now / config.windowMs)}`; | ||
| const redis = getRedisClient(); | ||
| if (!redis) { | ||
| logger?.log(`Rate limiting bypassed for ${key} (Redis disabled)`); | ||
| return { | ||
| allowed: true, | ||
| remaining: config.limit, | ||
| reset: Math.ceil((now + config.windowMs) / 1000), | ||
| }; | ||
| } | ||
| try { | ||
| const count = await redis.incr(windowKey); | ||
| if (count === 1) { | ||
| await redis.pexpire(windowKey, config.windowMs); | ||
| } | ||
| const ttl = await redis.pttl(windowKey); | ||
| const retryAfter = count > config.limit ? Math.ceil(ttl / 1000) : undefined; | ||
| const remaining = Math.max(config.limit - count, 0); | ||
| const reset = Math.ceil((now + ttl) / 1000); // Unix timestamp when reset will happen | ||
| if (count > config.limit) { | ||
| logger?.warn(`Rate limit exceeded for ${key}. Retry after ${retryAfter}s.`); | ||
| return { allowed: false, remaining: 0, retryAfter, reset }; | ||
| } | ||
| return { allowed: true, remaining, reset }; | ||
| } | ||
| catch (error) { | ||
| logger?.warn(`Rate limit backend unavailable for ${key}; allowing request.`); | ||
| logger?.warn(error); | ||
| return { | ||
| allowed: true, | ||
| remaining: config.limit, | ||
| reset: Math.ceil((now + config.windowMs) / 1000), | ||
| }; | ||
| } | ||
| } | ||
| function withRateLimiting(config) { | ||
| return async (req, context) => { | ||
| const path = new URL(req.url).pathname; | ||
| // ----- GLOBAL ----- | ||
| if (config.global) { | ||
| const result = await checkRateLimit("rate:global", config.global, context); | ||
| if (!result.allowed) { | ||
| context.extraOutputs.set("http", { | ||
| status: 429, | ||
| body: "Server is busy (global limit). Please retry later.", | ||
| headers: { | ||
| "Retry-After": result.retryAfter?.toString(), | ||
| "X-RateLimit-Limit": config.global.limit.toString(), | ||
| "X-RateLimit-Remaining": result.remaining.toString(), | ||
| "X-RateLimit-Reset": result.reset.toString(), | ||
| }, | ||
| }); | ||
| return false; | ||
| } | ||
| } | ||
| // ----- PER USER ----- | ||
| if (config.perUser) { | ||
| const userId = req.headers.get("x-user-id") || | ||
| req.headers.get("authorization") || | ||
| req.headers.get("x-forwarded-for") || | ||
| "anonymous"; | ||
| const result = await checkRateLimit(`rate:user:${userId}`, config.perUser, context); | ||
| if (!result.allowed) { | ||
| context.extraOutputs.set("http", { | ||
| status: 429, | ||
| body: "You are sending requests too fast (user limit). Please retry later.", | ||
| headers: { | ||
| "Retry-After": result.retryAfter?.toString(), | ||
| "X-RateLimit-Limit": config.perUser.limit.toString(), | ||
| "X-RateLimit-Remaining": result.remaining.toString(), | ||
| "X-RateLimit-Reset": result.reset.toString(), | ||
| }, | ||
| }); | ||
| return false; | ||
| } | ||
| } | ||
| // ----- PER API ----- | ||
| if (config.perApi) { | ||
| const apiKey = req.method + ":" + path; | ||
| const result = await checkRateLimit(`rate:api:${apiKey}`, config.perApi, context); | ||
| if (!result.allowed) { | ||
| context.extraOutputs.set("http", { | ||
| status: 429, | ||
| body: "This API is receiving too many requests. Please retry later.", | ||
| headers: { | ||
| "Retry-After": result.retryAfter?.toString(), | ||
| "X-RateLimit-Limit": config.perApi.limit.toString(), | ||
| "X-RateLimit-Remaining": result.remaining.toString(), | ||
| "X-RateLimit-Reset": result.reset.toString(), | ||
| }, | ||
| }); | ||
| return false; | ||
| } | ||
| } | ||
| // All passed | ||
| return true; | ||
| }; | ||
| } | ||
| //# sourceMappingURL=withRateLimiting.js.map |
| {"version":3,"file":"withRateLimiting.js","sourceRoot":"","sources":["../../src/middleware/withRateLimiting.ts"],"names":[],"mappings":"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"} |
| import type { Middleware } from "./withMiddleware"; | ||
| export declare function withSecurity(): Middleware; | ||
| //# sourceMappingURL=withSecurity.d.ts.map |
| {"version":3,"file":"withSecurity.d.ts","sourceRoot":"","sources":["../../src/middleware/withSecurity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD,wBAAgB,YAAY,IAAI,UAAU,CAwBzC"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withSecurity = withSecurity; | ||
| const index_js_1 = require("../utils/index.js"); | ||
| const transportSecurity_js_1 = require("./transportSecurity.js"); | ||
| function withSecurity() { | ||
| return async (request, context) => { | ||
| const { headers, cookies } = (0, index_js_1.getExtraOutputs)(context); | ||
| (0, transportSecurity_js_1.applyBaselineSecurityHeaders)(headers); | ||
| context.extraOutputs.set("headers", headers); | ||
| if ((0, transportSecurity_js_1.shouldEnforceHttps)() && | ||
| !(0, transportSecurity_js_1.isHttpsRequest)(request) && | ||
| !(0, transportSecurity_js_1.isInsecureLocalRequest)(request)) { | ||
| context.extraOutputs.set("http", { | ||
| status: 426, | ||
| headers, | ||
| cookies, | ||
| body: "HTTPS is required.", | ||
| }); | ||
| return Promise.resolve(false); | ||
| } | ||
| return Promise.resolve(true); | ||
| }; | ||
| } | ||
| //# sourceMappingURL=withSecurity.js.map |
| {"version":3,"file":"withSecurity.js","sourceRoot":"","sources":["../../src/middleware/withSecurity.ts"],"names":[],"mappings":";;AASA,oCAwBC;AA/BD,gDAAoD;AACpD,iEAKgC;AAChC,SAAgB,YAAY;IAC1B,OAAO,KAAK,EAAE,OAAoB,EAAE,OAA0B,EAAE,EAAE;QAChE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;QAEtD,IAAA,mDAA4B,EAAC,OAAO,CAAC,CAAC;QAEtC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE7C,IACE,IAAA,yCAAkB,GAAE;YACpB,CAAC,IAAA,qCAAc,EAAC,OAAO,CAAC;YACxB,CAAC,IAAA,6CAAsB,EAAC,OAAO,CAAC,EAChC,CAAC;YACD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE;gBAC/B,MAAM,EAAE,GAAG;gBACX,OAAO;gBACP,OAAO;gBACP,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC"} |
| import { Middleware } from "./withMiddleware.js"; | ||
| export declare const withSession: Middleware; | ||
| //# sourceMappingURL=withSession.d.ts.map |
| {"version":3,"file":"withSession.d.ts","sourceRoot":"","sources":["../../src/middleware/withSession.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAIjD,eAAO,MAAM,WAAW,EAAE,UAezB,CAAC"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.withSession = void 0; | ||
| const index_js_1 = require("../utils/index.js"); | ||
| const withSession = async (req, context) => { | ||
| const { cookies } = (0, index_js_1.getExtraOutputs)(context); | ||
| const session = (0, index_js_1.ensureSession)(req); | ||
| if (session.isNew && session.cookie) { | ||
| const newCookies = [...cookies, session.cookie]; | ||
| context.extraOutputs.set("cookies", newCookies); | ||
| } | ||
| context.extraInputs.set("sessionId", session.sessionId); | ||
| return true; | ||
| }; | ||
| exports.withSession = withSession; | ||
| //# sourceMappingURL=withSession.js.map |
| {"version":3,"file":"withSession.js","sourceRoot":"","sources":["../../src/middleware/withSession.ts"],"names":[],"mappings":";;;AAGA,gDAAmE;AAE5D,MAAM,WAAW,GAAe,KAAK,EAC1C,GAAgB,EAChB,OAA0B,EAC1B,EAAE;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAA,wBAAa,EAAC,GAAG,CAAC,CAAC;IAEnC,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAExD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAfW,QAAA,WAAW,eAetB"} |
| import { Cookie, InvocationContext } from "@azure/functions"; | ||
| export declare function getExtraOutputs(context: InvocationContext): { | ||
| headers: Headers; | ||
| cookies: Cookie[]; | ||
| }; | ||
| //# sourceMappingURL=context.d.ts.map |
| {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG;IAC3D,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAKA"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.getExtraOutputs = getExtraOutputs; | ||
| function getExtraOutputs(context) { | ||
| const headers = context.extraOutputs.get("headers") || new Headers(); | ||
| const cookies = context.extraOutputs.get("cookies") || []; | ||
| return { headers, cookies }; | ||
| } | ||
| //# sourceMappingURL=context.js.map |
| {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":";;AAEA,0CAQC;AARD,SAAgB,eAAe,CAAC,OAA0B;IAIxD,MAAM,OAAO,GACV,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAa,IAAI,IAAI,OAAO,EAAE,CAAC;IACpE,MAAM,OAAO,GAAI,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAc,IAAI,EAAE,CAAC;IACxE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC"} |
| import { HttpRequest } from "@azure/functions"; | ||
| export declare function extractAndHashClientIp(req: HttpRequest): string; | ||
| //# sourceMappingURL=extract.ip.d.ts.map |
| {"version":3,"file":"extract.ip.d.ts","sourceRoot":"","sources":["../../src/utils/extract.ip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM/C,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAQ/D"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.extractAndHashClientIp = extractAndHashClientIp; | ||
| const crypto_1 = require("crypto"); | ||
| const HMAC_SECRET = process.env.HMAC_SECRET || "OuYDwS9zpItZ9d84mIuZ+rzU6c9abFkzDWzXAPk4elg="; // Replace for production | ||
| function extractAndHashClientIp(req) { | ||
| const rawIp = req.headers.get("x-forwarded-for")?.split(",")[0].trim() || | ||
| req.headers.get("x-client-ip")?.trim() || | ||
| req.headers.get("host")?.trim() || | ||
| "unknown"; | ||
| const ip = (0, crypto_1.createHmac)("sha256", HMAC_SECRET).update(rawIp).digest("hex"); | ||
| return ip; | ||
| } | ||
| //# sourceMappingURL=extract.ip.js.map |
| {"version":3,"file":"extract.ip.js","sourceRoot":"","sources":["../../src/utils/extract.ip.ts"],"names":[],"mappings":";;AAMA,wDAQC;AAbD,mCAAoC;AAEpC,MAAM,WAAW,GACf,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,8CAA8C,CAAC,CAAC,yBAAyB;AAEtG,SAAgB,sBAAsB,CAAC,GAAgB;IACrD,MAAM,KAAK,GACT,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QACxD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE;QACtC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE;QAC/B,SAAS,CAAC;IACZ,MAAM,EAAE,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzE,OAAO,EAAE,CAAC;AACZ,CAAC"} |
| import { HttpResponseInit } from "@azure/functions"; | ||
| export declare const badRequestResponse: HttpResponseInit; | ||
| export declare const unauthorizedResponse: HttpResponseInit; | ||
| export declare const forbiddenResponse: HttpResponseInit; | ||
| export declare const notFoundResponse: HttpResponseInit; | ||
| export declare const requestTimeoutResponse: HttpResponseInit; | ||
| export declare const tooManyRequestsResponse: HttpResponseInit; | ||
| export declare const internalServerErrorResponse: HttpResponseInit; | ||
| export declare const notImplementedResponse: HttpResponseInit; | ||
| export declare const badGatewayResponse: HttpResponseInit; | ||
| export declare const serviceUnavailableResponse: HttpResponseInit; | ||
| export declare const gatewayTimeoutResponse: HttpResponseInit; | ||
| //# sourceMappingURL=http.errors.d.ts.map |
| {"version":3,"file":"http.errors.d.ts","sourceRoot":"","sources":["../../src/utils/http.errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEnD,eAAO,MAAM,kBAAkB,EAAE,gBAGhC,CAAA;AAED,eAAO,MAAM,oBAAoB,EAAE,gBAGlC,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,gBAG/B,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAG9B,CAAA;AAED,eAAO,MAAM,sBAAsB,EAAE,gBAGpC,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,gBAGrC,CAAA;AAED,eAAO,MAAM,2BAA2B,EAAE,gBAGzC,CAAA;AAED,eAAO,MAAM,sBAAsB,EAAE,gBAGpC,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAGhC,CAAA;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAGxC,CAAA;AAED,eAAO,MAAM,sBAAsB,EAAE,gBAGpC,CAAA"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.gatewayTimeoutResponse = exports.serviceUnavailableResponse = exports.badGatewayResponse = exports.notImplementedResponse = exports.internalServerErrorResponse = exports.tooManyRequestsResponse = exports.requestTimeoutResponse = exports.notFoundResponse = exports.forbiddenResponse = exports.unauthorizedResponse = exports.badRequestResponse = void 0; | ||
| exports.badRequestResponse = { | ||
| status: 400, | ||
| body: JSON.stringify({ error: 'Bad Request' }), | ||
| }; | ||
| exports.unauthorizedResponse = { | ||
| status: 401, | ||
| body: JSON.stringify({ error: 'Unauthorized' }), | ||
| }; | ||
| exports.forbiddenResponse = { | ||
| status: 403, | ||
| body: JSON.stringify({ error: 'Forbidden' }), | ||
| }; | ||
| exports.notFoundResponse = { | ||
| status: 404, | ||
| body: JSON.stringify({ error: 'Not Found' }), | ||
| }; | ||
| exports.requestTimeoutResponse = { | ||
| status: 408, | ||
| body: JSON.stringify({ error: 'Request Timeout' }), | ||
| }; | ||
| exports.tooManyRequestsResponse = { | ||
| status: 429, | ||
| body: JSON.stringify({ error: 'Too Many Requests' }), | ||
| }; | ||
| exports.internalServerErrorResponse = { | ||
| status: 500, | ||
| body: JSON.stringify({ error: 'Internal Server Error' }), | ||
| }; | ||
| exports.notImplementedResponse = { | ||
| status: 501, | ||
| body: JSON.stringify({ error: 'Not Implemented' }), | ||
| }; | ||
| exports.badGatewayResponse = { | ||
| status: 502, | ||
| body: JSON.stringify({ error: 'Bad Gateway' }), | ||
| }; | ||
| exports.serviceUnavailableResponse = { | ||
| status: 503, | ||
| body: JSON.stringify({ error: 'Service Unavailable' }), | ||
| }; | ||
| exports.gatewayTimeoutResponse = { | ||
| status: 504, | ||
| body: JSON.stringify({ error: 'Gateway Timeout' }), | ||
| }; | ||
| //# sourceMappingURL=http.errors.js.map |
| {"version":3,"file":"http.errors.js","sourceRoot":"","sources":["../../src/utils/http.errors.ts"],"names":[],"mappings":";;;AAEa,QAAA,kBAAkB,GAAqB;IAChD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;CACjD,CAAA;AAEY,QAAA,oBAAoB,GAAqB;IAClD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;CAClD,CAAA;AAEY,QAAA,iBAAiB,GAAqB;IAC/C,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;CAC/C,CAAA;AAEY,QAAA,gBAAgB,GAAqB;IAC9C,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;CAC/C,CAAA;AAEY,QAAA,sBAAsB,GAAqB;IACpD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;CACrD,CAAA;AAEY,QAAA,uBAAuB,GAAqB;IACrD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;CACvD,CAAA;AAEY,QAAA,2BAA2B,GAAqB;IACzD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;CAC3D,CAAA;AAEY,QAAA,sBAAsB,GAAqB;IACpD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;CACrD,CAAA;AAEY,QAAA,kBAAkB,GAAqB;IAChD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;CACjD,CAAA;AAEY,QAAA,0BAA0B,GAAqB;IACxD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;CACzD,CAAA;AAEY,QAAA,sBAAsB,GAAqB;IACpD,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;CACrD,CAAA"} |
| export * from "./cookies.js"; | ||
| export * from "./state.js"; | ||
| export * from "./http.errors.js"; | ||
| export * from "./extract.ip.js"; | ||
| export * from "./names.js"; | ||
| export * from "./context.js"; | ||
| export * from "./sanitize.table.key.js"; | ||
| export * from "./oauth-pkce.js"; | ||
| export * from "./session.js"; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC"} |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./cookies.js"), exports); | ||
| __exportStar(require("./state.js"), exports); | ||
| __exportStar(require("./http.errors.js"), exports); | ||
| __exportStar(require("./extract.ip.js"), exports); | ||
| __exportStar(require("./names.js"), exports); | ||
| __exportStar(require("./context.js"), exports); | ||
| __exportStar(require("./sanitize.table.key.js"), exports); | ||
| __exportStar(require("./oauth-pkce.js"), exports); | ||
| __exportStar(require("./session.js"), exports); | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,6CAA2B;AAC3B,mDAAiC;AACjC,kDAAgC;AAChC,6CAA2B;AAC3B,+CAA6B;AAC7B,0DAAwC;AACxC,kDAAgC;AAChC,+CAA6B"} |
| export declare function splitDisplayName(displayName: string): { | ||
| firstName: string; | ||
| middleName: string; | ||
| lastName: string; | ||
| }; | ||
| //# sourceMappingURL=names.d.ts.map |
| {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/utils/names.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAqBA"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.splitDisplayName = splitDisplayName; | ||
| function splitDisplayName(displayName) { | ||
| const parts = displayName.trim().split(/\s+/); | ||
| if (parts.length === 0) { | ||
| return { firstName: "", middleName: "", lastName: "" }; | ||
| } | ||
| if (parts.length === 1) { | ||
| return { firstName: parts[0], middleName: "", lastName: "" }; | ||
| } | ||
| if (parts.length === 2) { | ||
| return { firstName: parts[0], middleName: "", lastName: parts[1] }; | ||
| } | ||
| // 3 or more parts | ||
| const firstName = parts[0]; | ||
| const lastName = parts[parts.length - 1]; | ||
| const middleName = parts.slice(1, parts.length - 1).join(" "); | ||
| return { firstName, middleName, lastName }; | ||
| } | ||
| //# sourceMappingURL=names.js.map |
| {"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/utils/names.ts"],"names":[],"mappings":";;AAAA,4CAyBC;AAzBD,SAAgB,gBAAgB,CAAC,WAAmB;IAKlD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACzD,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC/D,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,CAAC;IAED,kBAAkB;IAClB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE9D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAC7C,CAAC"} |
| export declare function sanitizeUrlForPartitionKey(rawUrl: string): string; | ||
| //# sourceMappingURL=sanitize.table.key.d.ts.map |
| {"version":3,"file":"sanitize.table.key.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.table.key.ts"],"names":[],"mappings":"AAAA,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWjE"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.sanitizeUrlForPartitionKey = sanitizeUrlForPartitionKey; | ||
| function sanitizeUrlForPartitionKey(rawUrl) { | ||
| try { | ||
| const { hostname } = new URL(rawUrl); | ||
| const sanitized = hostname | ||
| .toLowerCase() | ||
| .replace(/[^a-z0-9]/g, "-") // convert all non-alphanumeric characters to hyphens | ||
| .replace(/^-+|-+$/g, ""); // remove leading/trailing hyphens | ||
| return sanitized; | ||
| } | ||
| catch { | ||
| throw new Error(`Invalid URL passed for sanitization: "${rawUrl}"`); | ||
| } | ||
| } | ||
| //# sourceMappingURL=sanitize.table.key.js.map |
| {"version":3,"file":"sanitize.table.key.js","sourceRoot":"","sources":["../../src/utils/sanitize.table.key.ts"],"names":[],"mappings":";;AAAA,gEAWC;AAXD,SAAgB,0BAA0B,CAAC,MAAc;IACvD,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,QAAQ;aACvB,WAAW,EAAE;aACb,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,qDAAqD;aAChF,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,kCAAkC;QAC9D,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,GAAG,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"} |
+18
-1
@@ -21,2 +21,18 @@ # Changelog | ||
| ## [1.0.6] - 2026-03-01 | ||
| - **Added** | ||
| - Public middleware export surface via package root and `@plasius/api/middleware` subpath. | ||
| - Middleware export-surface tests for root and middleware barrel coverage. | ||
| - **Changed** | ||
| - Root package now re-exports middleware primitives (`withMiddleware`, `withCors`, `withRateLimiting`, etc.). | ||
| - `withRateLimiting` now lazily initializes Redis clients to avoid import-time side effects. | ||
| - **Fixed** | ||
| - Removed middleware import-time Redis connection attempts that could emit runtime errors in consumer environments. | ||
| - **Security** | ||
| - (placeholder) | ||
| ## [1.0.5] - 2026-03-01 | ||
@@ -121,3 +137,3 @@ | ||
| [Unreleased]: https://github.com/Plasius-LTD/api/compare/v1.0.5...HEAD | ||
| [Unreleased]: https://github.com/Plasius-LTD/api/compare/v1.0.6...HEAD | ||
| [1.0.0]: https://github.com/Plasius-LTD/api/releases/tag/v1.0.0 | ||
@@ -129,1 +145,2 @@ [1.0.1]: https://github.com/Plasius-LTD/api/releases/tag/v1.0.1 | ||
| [1.0.5]: https://github.com/Plasius-LTD/api/releases/tag/v1.0.5 | ||
| [1.0.6]: https://github.com/Plasius-LTD/api/releases/tag/v1.0.6 |
+1
-0
| export { applyBaselineSecurityHeaders, isHttpsRequest, isInsecureLocalRequest, shouldEnforceHttps, } from "./middleware/transportSecurity.js"; | ||
| export * from "./middleware/index.js"; | ||
| export { decodeOAuthReturnToState, parseEncodedState, verifyState, } from "./utils/state.js"; | ||
@@ -3,0 +4,0 @@ export { generatePkceCodeChallenge, generatePkceCodeVerifier, generatePkceCookieId, getPkceCookieName, isValidPkceCodeVerifier, isValidPkceCookieId, } from "./utils/oauth-pkce.js"; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,cAAc,EACd,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,aAAa,EACb,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,cAAc,EACd,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mCAAmC,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,aAAa,EACb,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"} |
+15
-0
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -9,2 +23,3 @@ exports.getSessionIdFromRequest = exports.ensureSession = exports.createSessionCookie = exports.DEFAULT_SESSION_COOKIE_NAME = exports.isValidPkceCookieId = exports.isValidPkceCodeVerifier = exports.getPkceCookieName = exports.generatePkceCookieId = exports.generatePkceCodeVerifier = exports.generatePkceCodeChallenge = exports.verifyState = exports.parseEncodedState = exports.decodeOAuthReturnToState = exports.shouldEnforceHttps = exports.isInsecureLocalRequest = exports.isHttpsRequest = exports.applyBaselineSecurityHeaders = void 0; | ||
| Object.defineProperty(exports, "shouldEnforceHttps", { enumerable: true, get: function () { return transportSecurity_js_1.shouldEnforceHttps; } }); | ||
| __exportStar(require("./middleware/index.js"), exports); | ||
| var state_js_1 = require("./utils/state.js"); | ||
@@ -11,0 +26,0 @@ Object.defineProperty(exports, "decodeOAuthReturnToState", { enumerable: true, get: function () { return state_js_1.decodeOAuthReturnToState; } }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,0EAK2C;AAJzC,oIAAA,4BAA4B,OAAA;AAC5B,sHAAA,cAAc,OAAA;AACd,8HAAA,sBAAsB,OAAA;AACtB,0HAAA,kBAAkB,OAAA;AAGpB,6CAI0B;AAHxB,oHAAA,wBAAwB,OAAA;AACxB,6GAAA,iBAAiB,OAAA;AACjB,uGAAA,WAAW,OAAA;AAGb,uDAO+B;AAN7B,0HAAA,yBAAyB,OAAA;AACzB,yHAAA,wBAAwB,OAAA;AACxB,qHAAA,oBAAoB,OAAA;AACpB,kHAAA,iBAAiB,OAAA;AACjB,wHAAA,uBAAuB,OAAA;AACvB,oHAAA,mBAAmB,OAAA;AAGrB,iDAK4B;AAJ1B,yHAAA,2BAA2B,OAAA;AAC3B,iHAAA,mBAAmB,OAAA;AACnB,2GAAA,aAAa,OAAA;AACb,qHAAA,uBAAuB,OAAA"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0EAK2C;AAJzC,oIAAA,4BAA4B,OAAA;AAC5B,sHAAA,cAAc,OAAA;AACd,8HAAA,sBAAsB,OAAA;AACtB,0HAAA,kBAAkB,OAAA;AAEpB,wDAAsC;AAEtC,6CAI0B;AAHxB,oHAAA,wBAAwB,OAAA;AACxB,6GAAA,iBAAiB,OAAA;AACjB,uGAAA,WAAW,OAAA;AAGb,uDAO+B;AAN7B,0HAAA,yBAAyB,OAAA;AACzB,yHAAA,wBAAwB,OAAA;AACxB,qHAAA,oBAAoB,OAAA;AACpB,kHAAA,iBAAiB,OAAA;AACjB,wHAAA,uBAAuB,OAAA;AACvB,oHAAA,mBAAmB,OAAA;AAGrB,iDAK4B;AAJ1B,yHAAA,2BAA2B,OAAA;AAC3B,iHAAA,mBAAmB,OAAA;AACnB,2GAAA,aAAa,OAAA;AACb,qHAAA,uBAAuB,OAAA"} |
+9
-1
| { | ||
| "name": "@plasius/api", | ||
| "version": "1.0.5", | ||
| "version": "1.0.6", | ||
| "description": "Generic public API security and middleware helpers.", | ||
@@ -24,2 +24,10 @@ "private": false, | ||
| }, | ||
| "./middleware": { | ||
| "types": "./dist/middleware/index.d.ts", | ||
| "default": "./dist/middleware/index.js" | ||
| }, | ||
| "./middleware/*": { | ||
| "types": "./dist/middleware/*.d.ts", | ||
| "default": "./dist/middleware/*.js" | ||
| }, | ||
| "./package.json": "./package.json" | ||
@@ -26,0 +34,0 @@ }, |
+5
-0
@@ -54,2 +54,3 @@ # @plasius/api | ||
| - Main module: `@plasius/api` | ||
| - Middleware module: `@plasius/api/middleware` | ||
@@ -66,2 +67,6 @@ ### Example | ||
| ```ts | ||
| import { withCors, withRateLimiting, withMiddleware } from "@plasius/api/middleware"; | ||
| ``` | ||
| ## Local development | ||
@@ -68,0 +73,0 @@ |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 6 instances in 1 package
129291
64.81%107
148.84%1012
159.49%99
5.32%9
200%