Invoices: validate Saleor version and fail if lower than declared (#220)
* Invoices: validate Saleor version and fail if lower than decalred * Fix package lock * Replace tiny-invariant error to custom one to get explicit error message
This commit is contained in:
parent
38ea8324e8
commit
55c8f1afcb
4 changed files with 118 additions and 4 deletions
5
.changeset/good-camels-pull.md
Normal file
5
.changeset/good-camels-pull.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"saleor-app-invoices": minor
|
||||
---
|
||||
|
||||
App now validates Saleor version and will fail if lower than 3.10
|
|
@ -16,10 +16,11 @@
|
|||
"schemaVersion": "3.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": "^7.3.8",
|
||||
"@material-ui/core": "^4.12.4",
|
||||
"@material-ui/icons": "^4.11.3",
|
||||
"@material-ui/lab": "4.0.0-alpha.61",
|
||||
"@saleor/app-sdk": "0.29.0",
|
||||
"@saleor/app-sdk": "0.32.7",
|
||||
"@saleor/macaw-ui": "^0.7.2",
|
||||
"@sentry/nextjs": "^7.36.0",
|
||||
"@tanstack/react-query": "^4.24.4",
|
||||
|
|
|
@ -1,9 +1,29 @@
|
|||
import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next";
|
||||
|
||||
import { saleorApp } from "../../../saleor-app";
|
||||
import { gql } from "urql";
|
||||
import { createClient } from "../../lib/graphql";
|
||||
import { SaleorVersionQuery } from "../../../generated/graphql";
|
||||
import invariant from "tiny-invariant";
|
||||
import { createLogger } from "../../lib/logger";
|
||||
|
||||
const semver = require("semver");
|
||||
|
||||
const allowedUrlsPattern = process.env.ALLOWED_DOMAIN_PATTERN;
|
||||
|
||||
const SaleorVersion = gql`
|
||||
query SaleorVersion {
|
||||
shop {
|
||||
version
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* TODO: Move to Manifest, when implemented
|
||||
* @see https://github.com/saleor/saleor-app-sdk/pull/186
|
||||
*/
|
||||
const APP_SEMVER_REQUIREMENTS = ">=3.10";
|
||||
|
||||
/**
|
||||
* Required endpoint, called by Saleor to install app.
|
||||
* It will exchange tokens with app, so saleorApp.apl will contain token
|
||||
|
@ -25,4 +45,68 @@ export default createAppRegisterHandler({
|
|||
return true;
|
||||
},
|
||||
],
|
||||
/**
|
||||
* Check Saleor version and reject installation if it doesn't match
|
||||
*
|
||||
* TODO: Consider moving to app-sdk and do it under the hood
|
||||
*
|
||||
* Also, consume version, if possible, from the request directly
|
||||
* @see https://github.com/saleor/saleor/issues/12144
|
||||
*/
|
||||
async onRequestVerified(req, { authData: { token, saleorApiUrl }, respondWithError }) {
|
||||
const logger = createLogger({
|
||||
context: "onRequestVerified",
|
||||
});
|
||||
|
||||
try {
|
||||
const client = createClient(saleorApiUrl, async () => {
|
||||
return {
|
||||
token,
|
||||
};
|
||||
});
|
||||
|
||||
const saleorVersion = await client
|
||||
.query<SaleorVersionQuery>(SaleorVersion, {})
|
||||
.toPromise()
|
||||
.then((res) => {
|
||||
return res.data?.shop.version;
|
||||
});
|
||||
|
||||
logger.debug({ saleorVersion }, "Received saleor version from Shop query");
|
||||
|
||||
if (!saleorVersion) {
|
||||
throw new Error("Saleor Version couldnt be fetched from the API");
|
||||
}
|
||||
|
||||
const versionIsValid = semver.satisfies(
|
||||
semver.coerce(saleorVersion),
|
||||
APP_SEMVER_REQUIREMENTS
|
||||
);
|
||||
|
||||
logger.debug(
|
||||
{ saleorVersion, APP_SEMVER_REQUIREMENTS, coerced: semver.coerce(saleorVersion) },
|
||||
"Semver validation failed"
|
||||
);
|
||||
|
||||
if (!versionIsValid) {
|
||||
throw new Error(`App requires Saleor matching semver: ${APP_SEMVER_REQUIREMENTS}`);
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
const message = (e as Error)?.message ?? "Unknown error";
|
||||
|
||||
logger.debug({ message }, "Failed validating semver, will respond with error and status 400");
|
||||
|
||||
throw respondWithError({
|
||||
message: message,
|
||||
body: {
|
||||
success: false,
|
||||
error: {
|
||||
code: "INVALID_SALEOR_VERSION",
|
||||
message: message,
|
||||
},
|
||||
},
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -120,7 +120,7 @@ importers:
|
|||
'@material-ui/core': ^4.12.4
|
||||
'@material-ui/icons': ^4.11.3
|
||||
'@material-ui/lab': 4.0.0-alpha.61
|
||||
'@saleor/app-sdk': 0.29.0
|
||||
'@saleor/app-sdk': 0.32.7
|
||||
'@saleor/apps-shared': workspace:*
|
||||
'@saleor/macaw-ui': ^0.7.2
|
||||
'@sentry/nextjs': ^7.36.0
|
||||
|
@ -151,6 +151,7 @@ importers:
|
|||
react-dom: 18.2.0
|
||||
react-hook-form: ^7.41.0
|
||||
rimraf: ^3.0.2
|
||||
semver: ^7.3.8
|
||||
tiny-invariant: ^1.3.1
|
||||
typescript: 4.9.5
|
||||
urql: ^3.0.3
|
||||
|
@ -162,7 +163,7 @@ importers:
|
|||
'@material-ui/core': 4.12.4_5ndqzdd6t4rivxsukjv3i3ak2q
|
||||
'@material-ui/icons': 4.11.3_x54wk6dsnsxe7g7vvfmytp77te
|
||||
'@material-ui/lab': 4.0.0-alpha.61_x54wk6dsnsxe7g7vvfmytp77te
|
||||
'@saleor/app-sdk': 0.29.0_3vryta7zmbcsw4rrqf4axjqggm
|
||||
'@saleor/app-sdk': 0.32.7_3vryta7zmbcsw4rrqf4axjqggm
|
||||
'@saleor/apps-shared': link:../../packages/shared
|
||||
'@saleor/macaw-ui': 0.7.2_pmlnlm755hlzzzocw2qhf3a34e
|
||||
'@sentry/nextjs': 7.36.0_next@13.1.6+react@18.2.0
|
||||
|
@ -184,6 +185,7 @@ importers:
|
|||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
react-hook-form: 7.43.1_react@18.2.0
|
||||
semver: 7.3.8
|
||||
tiny-invariant: 1.3.1
|
||||
urql: 3.0.3_onqnqwb3ubg5opvemcqf7c2qhy
|
||||
usehooks-ts: 2.9.1_biqbaboplfbrettd7655fr4n2y
|
||||
|
@ -4054,6 +4056,28 @@ packages:
|
|||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@saleor/app-sdk/0.32.7_3vryta7zmbcsw4rrqf4axjqggm:
|
||||
resolution: {integrity: sha512-nt4ylAc+pq39LUFzPdlDvmLlvgWDo0K+qMAklvFjiPFGXfFRqTpWs9t9pqDMACiJLM5dvFAkGYJI2T6h/LUD8Q==}
|
||||
peerDependencies:
|
||||
next: '>=12'
|
||||
react: '>=17'
|
||||
react-dom: '>=17'
|
||||
dependencies:
|
||||
'@changesets/cli': 2.26.0
|
||||
debug: 4.3.4
|
||||
fast-glob: 3.2.12
|
||||
graphql: 16.6.0
|
||||
jose: 4.11.4
|
||||
next: 13.1.6_biqbaboplfbrettd7655fr4n2y
|
||||
raw-body: 2.5.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
retes: 0.33.0
|
||||
uuid: 8.3.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@saleor/macaw-ui/0.7.2_2dwar4pp5qoelfawvjffoi6dne:
|
||||
resolution: {integrity: sha512-Fli7fhTWuHu7q2CzxwTUpB4x9HYaxHSAzCLZLA23VY1ieIWbCxbsXadMiMGWp/nuYitswMr6JXMm+1SDe9K8LQ==}
|
||||
engines: {node: '>=16 <19'}
|
||||
|
|
Loading…
Reference in a new issue