Skip to content

Commit

Permalink
Merge pull request #341 from saleor/add-schema-version
Browse files Browse the repository at this point in the history
Parse schema version when processing saleor webhook
  • Loading branch information
krzysztofzuraw authored Feb 29, 2024
2 parents 0477c11 + 9e3d0cc commit 8789f37
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 30 deletions.
7 changes: 7 additions & 0 deletions .changeset/fair-ads-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@saleor/app-sdk": minor
---

Fix wrong logic introduced in [0.49.0](https://github.com/saleor/app-sdk/releases/tag/v0.49.0): there is not header `saleor-schema-version` when app-sdk is processing saleor webhook. This header is only present on install request.

Now app-sdk will try to parse version from `version` field on GraphQL subscription [Event](https://docs.saleor.io/docs/3.x/api-storefront/miscellaneous/interfaces/event#code-style-fontweight-normal-eventbversionbcodestring-). If field is not present `null` will be returned.
23 changes: 0 additions & 23 deletions src/handlers/next/saleor-webhooks/process-saleor-webhook.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ describe("processAsyncSaleorWebhook", () => {
"saleor-event": "product_updated",
"saleor-signature": "mocked_signature",
"content-length": "0", // is ignored by mocked raw-body.
"saleor-schema-version": "3.19",
},
method: "POST",
// body can be skipped because we mock it with raw-body
Expand Down Expand Up @@ -173,26 +172,4 @@ describe("processAsyncSaleorWebhook", () => {
schemaVersion: null,
});
});

it("Return schema version if saleor-schema-version header is present", async () => {
await expect(
processSaleorWebhook({
req: mockRequest,
apl: mockAPL,
allowedEvent: "PRODUCT_UPDATED",
})
).resolves.toStrictEqual({
authData: {
appId: "mock-app-id",
domain: "example.com",
jwks: "{}",
saleorApiUrl: "https://example.com/graphql/",
token: "mock-token",
},
baseUrl: "https://some-saleor-host.cloud",
event: "product_updated",
payload: {},
schemaVersion: 3.19,
});
});
});
19 changes: 12 additions & 7 deletions src/handlers/next/saleor-webhooks/process-saleor-webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { createDebug } from "../../../debug";
import { fetchRemoteJwks } from "../../../fetch-remote-jwks";
import { getBaseUrl, getSaleorHeaders } from "../../../headers";
import { getOtelTracer } from "../../../open-telemetry";
import { parseSchemaVersion } from "../../../util";
import { verifySignatureWithJwks } from "../../../verify-signature";

const debug = createDebug("processSaleorWebhook");
Expand Down Expand Up @@ -89,7 +90,7 @@ export const processSaleorWebhook: ProcessSaleorWebhook = async <T>({
throw new WebhookError("Wrong request method, only POST allowed", "WRONG_METHOD");
}

const { event, signature, saleorApiUrl, schemaVersion } = getSaleorHeaders(req.headers);
const { event, signature, saleorApiUrl } = getSaleorHeaders(req.headers);
const baseUrl = getBaseUrl(req.headers);

if (!baseUrl) {
Expand All @@ -107,10 +108,6 @@ export const processSaleorWebhook: ProcessSaleorWebhook = async <T>({
throw new WebhookError("Missing saleor-event header", "MISSING_EVENT_HEADER");
}

if (!schemaVersion) {
debug("Missing saleor-schema-version header");
}

const expected = allowedEvent.toLowerCase();

if (event !== expected) {
Expand Down Expand Up @@ -140,7 +137,7 @@ export const processSaleorWebhook: ProcessSaleorWebhook = async <T>({
throw new WebhookError("Missing request body", "MISSING_REQUEST_BODY");
}

let parsedBody: unknown;
let parsedBody: unknown & { version?: string | null };

try {
parsedBody = JSON.parse(rawBody);
Expand All @@ -150,6 +147,14 @@ export const processSaleorWebhook: ProcessSaleorWebhook = async <T>({
throw new WebhookError("Request body can't be parsed", "CANT_BE_PARSED");
}

let parsedSchemaVersion: number | null = null;

try {
parsedSchemaVersion = parseSchemaVersion(parsedBody.version);
} catch {
debug("Schema version cannot be parsed");
}

/**
* Verify if the app is properly installed for given Saleor API URL
*/
Expand Down Expand Up @@ -215,7 +220,7 @@ export const processSaleorWebhook: ProcessSaleorWebhook = async <T>({
event,
payload: parsedBody as T,
authData,
schemaVersion,
schemaVersion: parsedSchemaVersion,
};
} catch (err) {
const message = (err as Error)?.message ?? "Unknown error";
Expand Down
1 change: 1 addition & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./is-in-iframe";
export * from "./schema-version";
export * from "./use-is-mounted";
45 changes: 45 additions & 0 deletions src/util/schema-version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, expect, test } from "vitest";

import { parseSchemaVersion } from "./schema-version";

describe("parseSchemaVersion", () => {
test.each([
{
rawVersion: "3",
parsedVersion: null,
},
{
rawVersion: "3.19",
parsedVersion: 3.19,
},
{
rawVersion: "3.19.1",
parsedVersion: 3.19,
},
{
rawVersion: "malformed",
parsedVersion: null,
},
{
rawVersion: "malformed.raw",
parsedVersion: null,
},
{
rawVersion: "malformed.raw.version",
parsedVersion: null,
},
{
rawVersion: null,
parsedVersion: null,
},
{
rawVersion: undefined,
parsedVersion: null,
},
])(
"Parses version string from: $rawVersion to: $parsedVersion",
({ rawVersion, parsedVersion }) => {
expect(parseSchemaVersion(rawVersion)).toBe(parsedVersion);
}
);
});
15 changes: 15 additions & 0 deletions src/util/schema-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const parseSchemaVersion = (rawVersion: string | undefined | null): number | null => {
if (!rawVersion) {
return null;
}

const [majorString, minorString] = rawVersion.split(".");
const major = parseInt(majorString, 10);
const minor = parseInt(minorString, 10);

if (major && minor) {
return parseFloat(`${major}.${minor}`);
}

return null;
};

0 comments on commit 8789f37

Please sign in to comment.