diff --git a/package-lock.json b/package-lock.json index 6873f5f..d25f650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3006,7 +3006,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3024,11 +3025,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3041,15 +3044,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3152,7 +3158,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3162,6 +3169,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3174,17 +3182,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3201,6 +3212,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3273,7 +3285,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3283,6 +3296,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3358,7 +3372,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3388,6 +3403,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3405,6 +3421,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3443,11 +3460,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.3", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -4679,6 +4698,11 @@ "verror": "1.10.0" } }, + "jwt-decode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", + "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" + }, "keyv": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", diff --git a/package.json b/package.json index c86c93c..521666c 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "http-proxy": "^1.17.0", "inquirer": "^6.2.2", "inquirer-autocomplete-prompt": "^1.0.1", + "jwt-decode": "^2.2.0", "netlify": "2.4.1", "netlify-cli-logo": "^1.0.0", "node-fetch": "^2.3.0", diff --git a/src/utils/serve-functions.js b/src/utils/serve-functions.js index bb465b8..d31232f 100644 --- a/src/utils/serve-functions.js +++ b/src/utils/serve-functions.js @@ -6,6 +6,7 @@ const queryString = require("querystring"); const path = require("path"); const getPort = require("get-port"); const chokidar = require("chokidar"); +const jwtDecode = require("jwt-decode"); // const chalk = require("chalk"); const { NETLIFYDEVLOG, @@ -83,6 +84,26 @@ function promiseCallback(promise, callback) { // return path.join(functionPath, `${path.basename(functionPath)}.js`); // } +function buildClientContext(headers) { + // inject a client context based on auth header, ported over from netlify-lambda (https://github.com/netlify/netlify-lambda/pull/57) + if (!headers.authorization) return; + + const parts = headers.authorization.split(" "); + if (parts.length !== 2 || parts[0] !== "Bearer") return; + + try { + return { + identity: { + url: "NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_URL", + token: "NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_TOKEN" + }, + user: jwtDecode(parts[1]) + }; + } catch (_) { + // Ignore errors - bearer token is not a JWT, probably not intended for us + } +} + function createHandler(dir) { const functions = {}; fs.readdirSync(dir).forEach(file => { @@ -170,7 +191,11 @@ function createHandler(dir) { }; const callback = createCallback(response); - const promise = handler.handler(lambdaRequest, {}, callback); + const promise = handler.handler( + lambdaRequest, + { clientContext: buildClientContext(request.headers) || {} }, + callback + ); promiseCallback(promise, callback); }; }