Skip to content
Open
23 changes: 23 additions & 0 deletions spec/v2/providers/https.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,29 @@ describe("onCall", () => {
}
});

it("should not warn when using Expression-based enforceAppCheck during deployment", async () => {
const loggerSpy = sinon.spy(logger, "warn");
const enforceAppCheck = defineBoolean("ENFORCE_APP_CHECK");

try {
process.env.ENFORCE_APP_CHECK = "true";
process.env.FUNCTIONS_CONTROL_API = "true";

const func = https.onCall({ enforceAppCheck }, () => 42);

const req = request({ headers: { origin: "example.com" } }); // No app check token
const resp = await runHandler(func, req);

expect(resp.status).to.equal(401);
expect(loggerSpy.called).to.be.false;
} finally {
delete process.env.ENFORCE_APP_CHECK;
delete process.env.FUNCTIONS_CONTROL_API;
clearParams();
loggerSpy.restore();
}
});

it("overrides CORS headers if debug feature is enabled", async () => {
sinon.stub(debug, "isDebugFeatureEnabled").withArgs("enableCors").returns(true);

Expand Down
13 changes: 7 additions & 6 deletions src/common/providers/https.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { getApp } from "../app";
import { isDebugFeatureEnabled } from "../debug";
import { TaskContext } from "./tasks";
import { Expression } from "../../params";
import { valueOf } from "../../params/types";

const JWT_REGEX = /^[a-zA-Z0-9\-_=]+?\.[a-zA-Z0-9\-_=]+?\.([a-zA-Z0-9\-_=]+)?$/;

Expand Down Expand Up @@ -675,12 +676,12 @@ async function checkAppCheckToken(
if (isDebugFeatureEnabled("skipTokenVerification")) {
const decodedToken = unsafeDecodeAppCheckToken(appCheckToken);
appCheckData = { appId: decodedToken.app_id, token: decodedToken };
if (options.consumeAppCheckToken) {
if (valueOf(options.consumeAppCheckToken)) {
appCheckData.alreadyConsumed = false;
}
} else {
const appCheck = getAppCheck(getApp());
if (options.consumeAppCheckToken) {
if (valueOf(options.consumeAppCheckToken)) {
if (appCheck.verifyToken?.length === 1) {
const errorMsg =
"Unsupported version of the Admin SDK." +
Expand Down Expand Up @@ -768,8 +769,8 @@ export type CorsInfo = Omit<cors.CorsOptions, "origin"> & {
/** @internal **/
export interface CallableOptions<T = any> {
cors: CorsInfo;
enforceAppCheck?: boolean;
consumeAppCheckToken?: boolean;
enforceAppCheck?: boolean | Expression<boolean>;
consumeAppCheckToken?: boolean | Expression<boolean>;
/* @deprecated */
authPolicy?: (token: AuthData | null, data: T) => boolean | Promise<boolean>;
/**
Expand Down Expand Up @@ -882,15 +883,15 @@ function wrapOnCallHandler<Req = any, Res = any, Stream = unknown>(
throw new HttpsError("unauthenticated", "Unauthenticated");
}
if (tokenStatus.app === "INVALID") {
if (options.enforceAppCheck) {
if (valueOf(options.enforceAppCheck)) {
throw new HttpsError("unauthenticated", "Unauthenticated");
} else {
logger.warn(
"Allowing request with invalid AppCheck token because enforcement is disabled"
);
}
}
if (tokenStatus.app === "MISSING" && options.enforceAppCheck) {
if (tokenStatus.app === "MISSING" && valueOf(options.enforceAppCheck)) {
throw new HttpsError("unauthenticated", "Unauthenticated");
}

Expand Down
11 changes: 2 additions & 9 deletions src/v2/providers/https.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,15 +437,8 @@ export function onCall<T = any, Return = any | Promise<any>, Stream = unknown>(
// fix the length of handler to make the call to handler consistent
const fixedLen = (req: CallableRequest<T>, resp?: CallableResponse<Stream>) => handler(req, resp);

let enforceAppCheck = opts.enforceAppCheck ?? options.getGlobalOptions().enforceAppCheck;
if (enforceAppCheck instanceof Expression) {
enforceAppCheck = enforceAppCheck.value();
}

let consumeAppCheckToken = opts.consumeAppCheckToken;
if (consumeAppCheckToken instanceof Expression) {
consumeAppCheckToken = consumeAppCheckToken.value();
}
const enforceAppCheck = opts.enforceAppCheck ?? options.getGlobalOptions().enforceAppCheck;
const consumeAppCheckToken = opts.consumeAppCheckToken;

let func: any = onCallHandler(
{
Expand Down
Loading