Security
The Qumra SDK provides multiple layers of security to protect your app and verify the authenticity of requests.
JWT Verification
Use verifyJwt to validate JSON Web Tokens issued by the Qumra platform. This is useful for verifying session tokens and ensuring requests originate from authenticated users.
import { verifyJwt } from "@qumra/app-sdk";
const payload = verifyJwt(token, process.env.QUMRA_API_SECRET!);
if (payload) {
console.log("Token is valid:", payload);
console.log("Expires at:", payload.exp);
} else {
console.log("Token is invalid or expired");
}
Function Signature
function verifyJwt(token: string, secret: string): JwtPayload | null;
JwtPayload Interface
interface JwtPayload {
iss: string; // Issuer
sub: string; // Subject (store ID)
aud: string; // Audience (app ID)
exp: number; // Expiration time (Unix timestamp)
nbf: number; // Not before (Unix timestamp)
iat: number; // Issued at (Unix timestamp)
jti: string; // JWT ID (unique identifier)
[key: string]: unknown; // Additional custom claims
}
HMAC Verification
HMAC verification ensures that requests have not been tampered with and originate from the Qumra platform.
Query String Verification
Use verifyRequestHmac to verify the HMAC signature of incoming requests based on query string parameters. This is typically used for verifying app installation and OAuth callback requests.
import { verifyRequestHmac } from "@qumra/app-sdk";
const isValid = verifyRequestHmac(request, process.env.QUMRA_API_SECRET!);
if (!isValid) {
return Response.json({ error: "Invalid signature" }, { status: 401 });
}
Webhook Verification
Use verifyActionHmac to verify the HMAC signature of incoming webhook requests. This validates the request headers and extracts the webhook metadata.
import { verifyActionHmac } from "@qumra/app-sdk";
const result = verifyActionHmac(
request.headers,
process.env.QUMRA_API_SECRET!
);
if (result.isValid) {
console.log("Topic:", result.topic);
console.log("Store:", result.store);
console.log("Store ID:", result.storeId);
}
ActionHmacVerificationResult Interface
interface ActionHmacVerificationResult {
isValid: boolean; // Whether the HMAC signature is valid
topic: string; // Webhook topic (e.g., "product/create")
store: string; // Store domain
storeId: string; // Store unique identifier
webhookId: string; // Webhook subscription ID
requestId: string; // Unique request identifier
}
Request Validation
Bot Detection
Use validateNotBot to reject automated or suspicious requests. This is useful for protecting routes that should only be accessed by real users.
What it checks:
User-Agentheader presence and validityAcceptheader presence- Known bot patterns in the User-Agent string
import { validateNotBot } from "@qumra/app-sdk";
export async function loader({ request }: { request: Request }) {
validateNotBot(request);
// Continue with normal processing...
return Response.json({ message: "Hello, human!" });
}
Iframe Validation
Use validateIframeRequest to ensure that a request is coming from within a valid Qumra admin iframe context.
What it checks:
embedded=1query parameter is presentSec-Fetch-Dest: iframeheader- Cross-site request context
import { validateIframeRequest } from "@qumra/app-sdk";
export async function loader({ request }: { request: Request }) {
validateIframeRequest(request);
// Request is from a valid iframe context
return Response.json({ embedded: true });
}
Never expose your API secret. Store it in environment variables and never commit it to version control.