Skip to main content

Licenses and loans

Reading a license​

const license = await LCP.getLicense(bookPath);
Field
id, providerThe license and who issued it.
issued, updatedDates.
start, endThe loan window, when the license has one.
status'ready', 'active', 'revoked', 'returned', 'cancelled' or 'expired'.
charactersToCopyLeft, pagesToPrintLeftRights left; undefined when unlimited.
canRenewLoan, maxRenewDateWhether, and until when, the loan can be renewed.
canReturnPublicationWhether the book can be returned early.
restrictionWhy the book can't be read with this license, if it can't, such as licenseExpired; see Errors.

getLicense may ask the authentication handler for the passphrase. Pass { allowUserInteraction: false } to read only what doesn't need it.

Renewing and returning​

if (license.canRenewLoan) {
const renewed = await LCP.renewLoan(bookPath, { preferredEndDate });
}

if (license.canReturnPublication) {
await LCP.returnPublication(bookPath);
}

Without preferredEndDate, the provider picks the new end date.

Stored passphrases​

Readium remembers passphrases and licenses on the device:

WhatWhereReset
Passphrase hashesiOS Keychain; Android app databaseLCP.forgetPassphrases() (iOS only)
Licenses: device registration and consumed print/copy rightsiOS Keychain; Android app databaseNot exposed

Every stored passphrase is tried against each new license, so once a user's passphrase is known, their other books from the same provider open without asking. Call forgetPassphrases() when the user signs out or hands the device to someone else; each license then asks again.

To store a passphrase ahead of time, call LCP.addPassphrase(passphrase, { isHashed }) (iOS only).

Licenses can't be cleared on purpose: that would give back print and copy rights a user has spent. Deleting a book is just deleting its file.

Platform differences​

On Android, readium-lcp keeps its passphrase store internal, so addPassphrase and forgetPassphrases reject with unsupported; clearing the app's data is the only reset. Check LCP.capabilities to offer only what the platform supports:

function ForgetPassphrasesButton() {
if (!LCP.capabilities.forgetPassphrases) return null;
return (
<Button
title="Forget passphrases"
onPress={() => LCP.forgetPassphrases()}
/>
);
}