UNPKG

4.56 kBJavaScriptView Raw
1"use strict";
2// The MIT License (MIT)
3//
4// Copyright (c) 2022 Firebase
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22// SOFTWARE.
23Object.defineProperty(exports, "__esModule", { value: true });
24exports.onDispatchHandler = void 0;
25const logger = require("../../logger");
26const https = require("./https");
27/** @internal */
28function onDispatchHandler(handler) {
29 return async (req, res) => {
30 var _a;
31 try {
32 if (!https.isValidRequest(req)) {
33 logger.error("Invalid request, unable to process.");
34 throw new https.HttpsError("invalid-argument", "Bad Request");
35 }
36 const headers = {};
37 for (const [key, value] of Object.entries(req.headers)) {
38 if (!Array.isArray(value)) {
39 headers[key] = value;
40 }
41 }
42 const context = {
43 queueName: req.header("X-CloudTasks-QueueName"),
44 id: req.header("X-CloudTasks-TaskName"),
45 retryCount: req.header("X-CloudTasks-TaskRetryCount")
46 ? Number(req.header("X-CloudTasks-TaskRetryCount"))
47 : undefined,
48 executionCount: req.header("X-CloudTasks-TaskExecutionCount")
49 ? Number(req.header("X-CloudTasks-TaskExecutionCount"))
50 : undefined,
51 scheduledTime: req.header("X-CloudTasks-TaskETA"),
52 previousResponse: req.header("X-CloudTasks-TaskPreviousResponse")
53 ? Number(req.header("X-CloudTasks-TaskPreviousResponse"))
54 : undefined,
55 retryReason: req.header("X-CloudTasks-TaskRetryReason"),
56 headers,
57 };
58 if (!process.env.FUNCTIONS_EMULATOR) {
59 const authHeader = req.header("Authorization") || "";
60 const token = (_a = authHeader.match(/^Bearer (.*)$/)) === null || _a === void 0 ? void 0 : _a[1];
61 // Note: this should never happen since task queue functions are guarded by IAM.
62 if (!token) {
63 throw new https.HttpsError("unauthenticated", "Unauthenticated");
64 }
65 // We skip authenticating the token since tq functions are guarded by IAM.
66 const authToken = https.unsafeDecodeIdToken(token);
67 context.auth = {
68 uid: authToken.uid,
69 token: authToken,
70 };
71 }
72 const data = https.decode(req.body.data);
73 if (handler.length === 2) {
74 await handler(data, context);
75 }
76 else {
77 const arg = {
78 ...context,
79 data,
80 };
81 // For some reason the type system isn't picking up that the handler
82 // is a one argument function.
83 await handler(arg);
84 }
85 res.status(204).end();
86 }
87 catch (err) {
88 let httpErr = err;
89 if (!(err instanceof https.HttpsError)) {
90 // This doesn't count as an 'explicit' error.
91 logger.error("Unhandled error", err);
92 httpErr = new https.HttpsError("internal", "INTERNAL");
93 }
94 const { status } = httpErr.httpErrorCode;
95 const body = { error: httpErr.toJSON() };
96 res.status(status).send(body);
97 }
98 };
99}
100exports.onDispatchHandler = onDispatchHandler;