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"
|
"schemaVersion": "3.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"semver": "^7.3.8",
|
||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
"@material-ui/icons": "^4.11.3",
|
"@material-ui/icons": "^4.11.3",
|
||||||
"@material-ui/lab": "4.0.0-alpha.61",
|
"@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",
|
"@saleor/macaw-ui": "^0.7.2",
|
||||||
"@sentry/nextjs": "^7.36.0",
|
"@sentry/nextjs": "^7.36.0",
|
||||||
"@tanstack/react-query": "^4.24.4",
|
"@tanstack/react-query": "^4.24.4",
|
||||||
|
|
|
@ -1,9 +1,29 @@
|
||||||
import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next";
|
import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next";
|
||||||
|
|
||||||
import { saleorApp } from "../../../saleor-app";
|
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 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.
|
* Required endpoint, called by Saleor to install app.
|
||||||
* It will exchange tokens with app, so saleorApp.apl will contain token
|
* It will exchange tokens with app, so saleorApp.apl will contain token
|
||||||
|
@ -25,4 +45,68 @@ export default createAppRegisterHandler({
|
||||||
return true;
|
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/core': ^4.12.4
|
||||||
'@material-ui/icons': ^4.11.3
|
'@material-ui/icons': ^4.11.3
|
||||||
'@material-ui/lab': 4.0.0-alpha.61
|
'@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/apps-shared': workspace:*
|
||||||
'@saleor/macaw-ui': ^0.7.2
|
'@saleor/macaw-ui': ^0.7.2
|
||||||
'@sentry/nextjs': ^7.36.0
|
'@sentry/nextjs': ^7.36.0
|
||||||
|
@ -151,6 +151,7 @@ importers:
|
||||||
react-dom: 18.2.0
|
react-dom: 18.2.0
|
||||||
react-hook-form: ^7.41.0
|
react-hook-form: ^7.41.0
|
||||||
rimraf: ^3.0.2
|
rimraf: ^3.0.2
|
||||||
|
semver: ^7.3.8
|
||||||
tiny-invariant: ^1.3.1
|
tiny-invariant: ^1.3.1
|
||||||
typescript: 4.9.5
|
typescript: 4.9.5
|
||||||
urql: ^3.0.3
|
urql: ^3.0.3
|
||||||
|
@ -162,7 +163,7 @@ importers:
|
||||||
'@material-ui/core': 4.12.4_5ndqzdd6t4rivxsukjv3i3ak2q
|
'@material-ui/core': 4.12.4_5ndqzdd6t4rivxsukjv3i3ak2q
|
||||||
'@material-ui/icons': 4.11.3_x54wk6dsnsxe7g7vvfmytp77te
|
'@material-ui/icons': 4.11.3_x54wk6dsnsxe7g7vvfmytp77te
|
||||||
'@material-ui/lab': 4.0.0-alpha.61_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/apps-shared': link:../../packages/shared
|
||||||
'@saleor/macaw-ui': 0.7.2_pmlnlm755hlzzzocw2qhf3a34e
|
'@saleor/macaw-ui': 0.7.2_pmlnlm755hlzzzocw2qhf3a34e
|
||||||
'@sentry/nextjs': 7.36.0_next@13.1.6+react@18.2.0
|
'@sentry/nextjs': 7.36.0_next@13.1.6+react@18.2.0
|
||||||
|
@ -184,6 +185,7 @@ importers:
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
react-dom: 18.2.0_react@18.2.0
|
react-dom: 18.2.0_react@18.2.0
|
||||||
react-hook-form: 7.43.1_react@18.2.0
|
react-hook-form: 7.43.1_react@18.2.0
|
||||||
|
semver: 7.3.8
|
||||||
tiny-invariant: 1.3.1
|
tiny-invariant: 1.3.1
|
||||||
urql: 3.0.3_onqnqwb3ubg5opvemcqf7c2qhy
|
urql: 3.0.3_onqnqwb3ubg5opvemcqf7c2qhy
|
||||||
usehooks-ts: 2.9.1_biqbaboplfbrettd7655fr4n2y
|
usehooks-ts: 2.9.1_biqbaboplfbrettd7655fr4n2y
|
||||||
|
@ -4054,6 +4056,28 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
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:
|
/@saleor/macaw-ui/0.7.2_2dwar4pp5qoelfawvjffoi6dne:
|
||||||
resolution: {integrity: sha512-Fli7fhTWuHu7q2CzxwTUpB4x9HYaxHSAzCLZLA23VY1ieIWbCxbsXadMiMGWp/nuYitswMr6JXMm+1SDe9K8LQ==}
|
resolution: {integrity: sha512-Fli7fhTWuHu7q2CzxwTUpB4x9HYaxHSAzCLZLA23VY1ieIWbCxbsXadMiMGWp/nuYitswMr6JXMm+1SDe9K8LQ==}
|
||||||
engines: {node: '>=16 <19'}
|
engines: {node: '>=16 <19'}
|
||||||
|
|
Loading…
Reference in a new issue