Entitlement check
Check whether a grantee is permitted to perform actions in your system.
Any plans the grantee is subscribed to are included in the entitlement check, alongside their features.
- JS SDK
- Node SDK
- Fetch
- cURL
import { getGrantee } from '@salable/js';
const { hasFeature } = await getGrantee({
apiKey: 'your-salable-api-key',
productUuid: 'your-products-uuid',
granteeId: 'your-grantees-id',
});
// Check for a boolean feature
const hasAccessToCsvExport = hasFeature('csv-export');
// or a plan
const hasProPlan = hasFeature('pro');
import { initSalable } from '@salable/node-sdk';
const salable = initSalable('your-salable-api-key', 'v3');
const { features } = await salable.entitlements.check({
productUuid: 'your-product-uuid',
granteeIds: ['your-grantees-id'],
});
const hasAccessToFeature = features.some((f) => {f.feature === 'your-feature-name'});
const params = new URLSearchParams();
params.append("granteeIds", "id-of-grantee");
params.append("productUuid", "your-product-uuid");
const response = await fetch(`https://api.salable.app/entitlements/check?${params}`, {
headers: {
"x-api-key": "your-salable-api-key",
version: "v3"
},
})
const check = await response.json();
curl
-XGET
-H 'x-api-key: your_salable_api_key'
-H 'version: v3'
'https://api.salable.app/entitlements/check?productUuid=your_product_uuid&granteeIds=your-grantees-id'
Verifying Signatures
Signatures can be verified using the signature
and features
from the entitlements check and your organisations public key
ECDSA Encryption and Signatures
We use ECDSA cryptography to generate signatures for entitlements checks. Signatures are signed with a private key (which we keep encrypted on our end) and can be verified using your organisations public key
NOTE: You can request entitlement-check signatures to be encoded in the P1363 encoding using the "sigEncode=P1363" query string in the request
- The P1363 encoding allows for signature verification on web browsers
Signature verification examples:
- JS SDK
- Javascript
import { verifyLicenseCheck } from '@salable/js';
var isValid = await verifyLicenseCheck({
publicKey: 'your_public_key',
signature: 'entitlement_check_signature',
payload: 'entitlement_check_payload'
});
<script>
// Utility Functions
function importPublicKey(publicKeyPem) {
const pemContents = publicKeyPem.replace(/-{5}.*?-{5}|\s/gm, '');
const binaryDerString = window.atob(pemContents);
const binaryDer = stringToArrayBuffer(binaryDerString);
return window.crypto.subtle.importKey(
"spki",
binaryDer,
{
name: "ECDSA",
namedCurve: "P-256",
},
true,
["verify"],
);
}
function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
function hexStringToUint8Array(hexString: string) {
const result = new Uint8Array(hexString.length / 2);
for (let i = 0; i < hexString.length; i += 2) {
result[i / 2] = parseInt(hexString.substring(i, i + 2), 16);
}
return result;
}
async function verifyLicenseCheck(yourPublicKey, signature, features) {
const publicKey = await importPublicKey(yourPublicKey);
const rawSignature = hexStringToUint8Array(signature);
return await window.crypto.subtle.verify(
{
name: 'ECDSA',
hash: { name: 'SHA-256' }
},
publicKey,
rawSignature.buffer,
new TextEncoder().encode(features)
);
}
</script>