You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

firebase-functions

Package Overview
Dependencies
Maintainers
4
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

firebase-functions - npm Package Compare versions

Comparing version

to
6.1.2

13

lib/common/providers/https.d.ts

@@ -93,4 +93,17 @@ /// <reference types="node" />

export interface CallableProxyResponse {
/**
* Writes a chunk of the response body to the client. This method can be called
* multiple times to stream data progressively.
*/
write: express.Response["write"];
/**
* Indicates whether the client has requested and can handle streaming responses.
* This should be checked before attempting to stream data to avoid compatibility issues.
*/
acceptsStreaming: boolean;
/**
* An AbortSignal that is triggered when the client disconnects or the
* request is terminated prematurely.
*/
signal: AbortSignal;
}

@@ -97,0 +110,0 @@ /**

103

lib/common/providers/https.js

@@ -24,3 +24,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.onCallHandler = exports.checkAuthToken = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.unsafeDecodeToken = exports.decode = exports.encode = exports.isValidRequest = exports.HttpsError = exports.ORIGINAL_AUTH_HEADER = exports.CALLABLE_AUTH_HEADER = void 0;
exports.onCallHandler = exports.checkAuthToken = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.unsafeDecodeToken = exports.decode = exports.encode = exports.isValidRequest = exports.HttpsError = exports.DEFAULT_HEARTBEAT_SECONDS = exports.ORIGINAL_AUTH_HEADER = exports.CALLABLE_AUTH_HEADER = void 0;
const cors = require("cors");

@@ -39,2 +39,4 @@ const logger = require("../../logger");

exports.ORIGINAL_AUTH_HEADER = "x-original-auth";
/** @internal */
exports.DEFAULT_HEARTBEAT_SECONDS = 30;
/**

@@ -408,2 +410,26 @@ * Standard error codes and HTTP statuses for different ways a request can fail,

return async (req, res) => {
const abortController = new AbortController();
let heartbeatInterval = null;
const heartbeatSeconds = options.heartbeatSeconds === undefined ? exports.DEFAULT_HEARTBEAT_SECONDS : options.heartbeatSeconds;
const clearScheduledHeartbeat = () => {
if (heartbeatInterval) {
clearTimeout(heartbeatInterval);
heartbeatInterval = null;
}
};
const scheduleHeartbeat = () => {
clearScheduledHeartbeat();
if (!abortController.signal.aborted) {
heartbeatInterval = setTimeout(() => {
if (!abortController.signal.aborted) {
res.write(": ping\n");
scheduleHeartbeat();
}
}, heartbeatSeconds * 1000);
}
};
res.on("close", () => {
clearScheduledHeartbeat();
abortController.abort();
});
try {

@@ -476,12 +502,22 @@ if (!isValidRequest(req)) {

};
// TODO: set up optional heartbeat
const responseProxy = {
write(chunk) {
if (acceptsStreaming) {
const formattedData = encodeSSE({ message: chunk });
return res.write(formattedData);
// if client doesn't accept sse-protocol, response.write() is no-op.
if (!acceptsStreaming) {
return false;
}
// if client doesn't accept sse-protocol, response.write() is no-op.
// if connection is already closed, response.write() is no-op.
if (abortController.signal.aborted) {
return false;
}
const formattedData = encodeSSE({ message: chunk });
const wrote = res.write(formattedData);
// Reset heartbeat timer after successful write
if (wrote && heartbeatInterval !== null && heartbeatSeconds > 0) {
scheduleHeartbeat();
}
return wrote;
},
acceptsStreaming,
signal: abortController.signal,
};

@@ -491,2 +527,5 @@ if (acceptsStreaming) {

res.status(200);
if (heartbeatSeconds !== null && heartbeatSeconds > 0) {
scheduleHeartbeat();
}
}

@@ -496,32 +535,46 @@ // For some reason the type system isn't picking up that the handler

result = await handler(arg, responseProxy);
clearScheduledHeartbeat();
}
// Encode the result as JSON to preserve types like Dates.
result = encode(result);
// If there was some result, encode it in the body.
const responseBody = { result };
if (acceptsStreaming) {
res.write(encodeSSE(responseBody));
res.end();
if (!abortController.signal.aborted) {
// Encode the result as JSON to preserve types like Dates.
result = encode(result);
// If there was some result, encode it in the body.
const responseBody = { result };
if (acceptsStreaming) {
res.write(encodeSSE(responseBody));
res.end();
}
else {
res.status(200).send(responseBody);
}
}
else {
res.status(200).send(responseBody);
res.end();
}
}
catch (err) {
let httpErr = err;
if (!(err instanceof HttpsError)) {
// This doesn't count as an 'explicit' error.
logger.error("Unhandled error", err);
httpErr = new HttpsError("internal", "INTERNAL");
if (!abortController.signal.aborted) {
let httpErr = err;
if (!(err instanceof HttpsError)) {
// This doesn't count as an 'explicit' error.
logger.error("Unhandled error", err);
httpErr = new HttpsError("internal", "INTERNAL");
}
const { status } = httpErr.httpErrorCode;
const body = { error: httpErr.toJSON() };
if (version === "gcfv2" && req.header("accept") === "text/event-stream") {
res.send(encodeSSE(body));
}
else {
res.status(status).send(body);
}
}
const { status } = httpErr.httpErrorCode;
const body = { error: httpErr.toJSON() };
if (version === "gcfv2" && req.header("accept") === "text/event-stream") {
res.send(encodeSSE(body));
}
else {
res.status(status).send(body);
res.end();
}
}
finally {
clearScheduledHeartbeat();
}
};
}

@@ -135,2 +135,9 @@ import * as express from "express";

consumeAppCheckToken?: boolean;
/**
* Time in seconds between sending heartbeat messages to keep the connection
* alive. Set to `null` to disable heartbeats.
*
* Defaults to 30 seconds.
*/
heartbeatSeconds?: number | null;
}

@@ -137,0 +144,0 @@ /**

@@ -139,2 +139,3 @@ "use strict";

consumeAppCheckToken: opts.consumeAppCheckToken,
heartbeatSeconds: opts.heartbeatSeconds,
}, fixedLen, "gcfv2");

@@ -141,0 +142,0 @@ func = (0, trace_1.wrapTraceContext)((0, onInit_1.withInit)(func));

{
"name": "firebase-functions",
"version": "6.1.1",
"version": "6.1.2",
"description": "Firebase SDK for Cloud Functions",

@@ -290,3 +290,3 @@ "keywords": [

"@types/node-fetch": "^3.0.3",
"@types/sinon": "^7.0.13",
"@types/sinon": "^9.0.11",
"@typescript-eslint/eslint-plugin": "^5.33.1",

@@ -317,3 +317,3 @@ "@typescript-eslint/parser": "^5.33.1",

"semver": "^7.3.5",
"sinon": "^7.3.2",
"sinon": "^9.2.4",
"ts-node": "^10.4.0",

@@ -320,0 +320,0 @@ "typescript": "^4.3.5",