-
Notifications
You must be signed in to change notification settings - Fork 1
Express.js Documentation
This package exposes a set of typescript-ready Express Middlewares / routers to let you focus on your business logic integration. In this document, they are organized per Apple Service.
Before using this library, a look at the Apple Documentation for Wallet webservice is suggested, in order to understand how the business logic should be developed and how data should be saved.
Each endpoint documented by Apple in its documentation can be seen as a Router as you might not want add all of them, or add them conditionally based on the environment. They are also organized by endpoint version and by endpoint name.
This package is studied to be compatible only with ESM.
It exposes the following entry points in package.json
:
{
".": "./lib/index.js",
"./v1": "./lib/middlewares/v1/index.js",
"./v1/*": "./lib/middlewares/v1/*"
}
Therefore they can be imported in the following ways:
import { v1 } from "express-passkit-webservice";
import { ... } from "express-passkit-webservice/v1";
import logRouter from "express-passkit-webservice/v1/log.js";
and can be added to Express in the following way, through the direct entry point:
app.use((await import("express-passkit-webservice/v1/registration.js").default({
...middlewareOpts
}));
or
import registrationRouter from "express-passkit-webservice/v1/registration.js";
app.use(registrationRouter({
...middlwareOpts
}));
Note
Custom prefixes can be used as well, like follows. However, you need to pay attention that your pass.json
will include such custom prefix as well, inside the webServiceURL
import registrationRouter from "express-passkit-webservice/v1/registration.js";
app.use("/apple/wallet/", registrationRouter({
...middlewareOpts
}));
Each middleware accepts some mandatory callbacks. If not provided, the router will throw a HandlerNotFoundError
.
Some endpoints require, by Apple specification, a token to be set in the pass.json
file inside the .pkpass
bundle.
In order to let you implement your own token validation logic, some middlewares allow you to specify an async function, that will let you implement the token validation logic.
A light validation is performed directly by the middlewares by looking at the Authorization Schema for it to be ApplePass
.
This package is fully compatible with a NestJS application that uses @nestjs/platform-express
(the default). Middlewares can be imported as specified above in the src/main.ts
file, in the boostrap()
function, where the app gets created.
/** src/main.ts **/
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(
"/pass", /** Custom prefix, if desired **/
(await import("express-passkit-webservice/v1/registration.js")).default({
async onRegister(
deviceLibraryIdentifier,
passTypeIdentifier,
serialNumber,
pushToken,
) {
/** Your implementation **/
},
async onUnregister(
deviceLibraryIdentifier,
passTypeIdentifier,
serialNumber,
) {
/** Your implementation **/
},
async tokenVerifier(token) {
console.log("Verifying token", token);
return true;
},
}),
);
await app.listen(process.env.PORT ?? 3000);
}
References:
- https://developer.apple.com/documentation/walletpasses/register_a_pass_for_update_notifications
- https://developer.apple.com/documentation/walletpasses/unregister_a_pass_for_update_notifications
Entrypoint: express-passkit-webservice/v1/registration.js
.
Description:
This middleware wraps both device registration and unregistration endpoints as they are coupled.
Default exports: RegistrationRouter
declare function RegistrationRouter(...);
export default RegistrationRouter;
Middleware callbacks:
-
onRegister
(mandatory)
onRegister(deviceLibraryIdentifier: string, passTypeIdentifier: string, serialNumber: string, pushToken: string): PromiseLike<boolean>;
-
onUnregister
(mandatory)
onUnregister(deviceLibraryIdentifier: string, passTypeIdentifier: string, serialNumber: string): PromiseLike<boolean>;
-
tokenVerifier
(optional)
Can be used to verify the token sent by Apple Wallet and that is available in a pass. If set, this function is called before both onRegister
and onUnregister
.
tokenVerifier?(token: string): PromiseLike<boolean>;
References:
Entrypoint: express-passkit-webservice/v1/update.js
.
Description:
This middleware wraps the request for a Pass update made by Apple Wallet on two occasions:
- Manual refresh by the user
- Refresh by application following an APNS notification by your server and the
list
endpoint invocation (see below for the middleware).
Default exports: UpdateRouter
declare function UpdateRouter(...);
export default UpdateRouter;
Middleware callbacks:
-
onUpdateRequest
(mandatory)
Generate your pass when this callback is received. You can use whatever system you want to generate a pass, but you might find passkit-generator interesting for this.
Returning undefined
will make the call to return HTTP 304
, as per Apple (legacy) documentation. Otherwise, HTTP 200
will be returned.
Returning something else, except undefined
and Uint8Array
will make the call to return HTTP 500
.
onUpdateRequest(passTypeIdentifier: string, serialNumber: string): PromiseLike<Uint8Array | undefined>;
-
tokenVerifier
(optional)
Can be used to verify the token sent by Apple Wallet and that is available in a pass. If set, this function is called before both onUpdateRequest
.
tokenVerifier?(token: string): PromiseLike<boolean>;
References:
Entrypoint: express-passkit-webservice/v1/list.js
.
Description:
This middleware wraps the request for changed passes that Apple Wallet sends after receiving an APNS notification.
After the list of updated serial numbers is provided, Apple Wallet will use that information to perform a request per serial number to your update
middleware.
Default exports: ListRouter
declare function ListRouter<LastUpdatedFormat = unknown>(...);
export default ListRouter;
Middleware callbacks:
-
onListRetrieve
(mandatory)
This endpoint is called with two parameters and a query string: passesUpdatedSince
. This value is the value you sent in the previous list
request (won't be provided, therefore, on the first request).
As the format is not enforced by Apple specifications, for Typescript LastUpdatedFormat
is set to be unknown
and can be specified in the middleware signature or casted when you use the function.
onListRetrieve(deviceLibraryIdentifier: string, passTypeIdentifier: string, filters: {
passesUpdatedSince?: LastUpdatedFormat
}): PromiseLike<SerialNumbers | undefined>;
References:
Entrypoint: express-passkit-webservice/v1/log.js
.
Description:
This middleware wraps the request Apple will perform in case of logs. Logs may contain records about failed requests (e.g. missing endpoints or bad status code).
Default exports: LogRouter
declare function LogRouter(...);
export default LogRouter;
Middleware callbacks:
-
onIncomingLogs
(mandatory)
onIncomingLogs(logs: string[]): void;