@playstack/devices
Registered device identity, encrypted push targets, trust state, and atomic revocation.
Pro. Covered by the Playstack Pro License. Registry access is required; check preview availability before installing. See package access.
@playstack/devices gives authentication, MFA, and notification features one shared registered-device identity without making any of those packages own it.
Install
npm install @playstack/devices @playstack/core @playstack/eventsCompose the service
import { createDevices } from '@playstack/devices'
export const devices = createDevices({
persistence,
cipher: applicationCrypto,
events,
clock,
ids,
lastSeenWriteIntervalMs: 60 * 60_000,
})
await devices.registerDevice({
id: installationId,
userId,
appId: 'synth',
platform: 'ios',
appVersion: '2.4.0',
})Configuration reference
DevicesOptions property | Required | Purpose |
|---|---|---|
persistence | Yes | Transactional devices, encrypted push records, and revocation state. |
cipher | Yes | Encrypts and decrypts push bearer credentials. |
events | Yes | Publishes registered, trusted, and revoked lifecycle events. |
clock, ids | Yes | Application-owned time and identifiers. |
lastSeenWriteIntervalMs | No | Non-negative write throttle; defaults to one hour. |
Device and push properties
Device registration accepts an application installation id, userId, appId, platform (android, ios, macos, or web), and optional name, model, OS version, and app version. Trust always has an absolute expiry and never slides when the device is seen.
Push registration accepts a device/user pair, transport (apns, expo, fcm, or webpush), credential, and optional prior push-token ID for atomic rotation. Web Push uses { endpoint, keys: { auth, p256dh } }; other transports use an opaque string.
Auth session validation
assertActive(userId, deviceId) resolves only while the device exists, belongs to the user, and is not revoked, so the service satisfies the DeviceSessionValidator contract of @playstack/auth without an adapter.
const sessions = databaseSessions({ persistence, crypto, events, clock, ids, deviceValidator: devices, requireDevice: true })
events.registerInternal('devices.device.revoked', sessions.deviceRevocationHandler())In NestJS, provide the service under NEST_DEVICE_SESSION_VALIDATOR and @playstack/nest-auth injects it into the session factory.
Bridge contracts
| Contract | Key members |
|---|---|
SecretCipher | encrypt(plaintext) and decryptText(ciphertext); compatible with @playstack/crypto. |
DevicesPersistence | Transaction, device lookup/save/list, push lookup/save/list, and bulk invalidation. |
The persistence transaction handle is also used by synchronous auth and audit handlers. Revocation must invalidate push records and publish devices.device.revoked atomically so auth can revoke device-backed sessions in the same transaction.
import { prismaDevicesPersistence } from '@playstack/devices/prisma'
const persistence = prismaDevicesPersistence(prisma)The Prisma adapter serializes registration and locks token rotation and revocation rows. The managed, non-ejectable schema remains application-migrated. Test adapters are available from @playstack/devices/testing.
Boundary
The package does not fingerprint visitors, pair devices, deliver notifications, or store auth sessions. Auth and MFA depend on its explicit validator/trust methods and events; devices remains independent of both.
API entry points and requirements
Reference snapshot: @playstack/devices@0.1.0-beta.1. Import only the entry point your runtime needs. Paths below are relative to the installed package; use Go to Definition in your editor to inspect exact parameters, return types and overloads. Do not import the declaration-file paths directly.
| Public entry point | Declaration file |
|---|---|
@playstack/devices | ./dist/index.d.ts |
@playstack/devices/errors | ./dist/errors.d.ts |
@playstack/devices/prisma | ./dist/prisma.d.ts |
@playstack/devices/testing | ./dist/testing.d.ts |
@playstack/devices/playstack.artifacts.json | No TypeScript declaration (asset or metadata export). |
@playstack/devices/package.json | No TypeScript declaration (asset or metadata export). |
Node.js engine requirement: >=20. This is not a claim that every entry point works in browsers or Workers.
Peer dependencies
This package declares no peer dependencies. Its ordinary dependencies are resolved by the package manager.
For a complete first program, start with Getting started. For API lookup and partial-example conventions, see Reading the reference. Provider failures, lifecycle requirements and application responsibilities remain described in the guide above; types alone do not establish production safety.