Repository navigation
v6.8.0
Highlights
@byline/admin,@byline/host-tanstack-start,@byline/auth,@byline/core: Optional passkey sign-in for admin users. Admins can now add passkeys from their Account page and sign in with them from the sign-in page, alongside password sign-in, which is unchanged and stays available. Adding or removing a passkey, or confirming an action with one, requires fresh proof with the account's password or one of its own passkeys, and removing a passkey signs that account out on every device. Passkeys are created on the user's own authenticator (a phone, a laptop, a password manager or a security key), so nobody, including an admin, can create one for someone else. For account recovery, a role with the newadmin.users.managePasskeysability can review and remove another user's passkeys, and each recovery removal is written to the audit log; only a super-admin can manage another super-admin's passkeys. Passkeys stay off until a site configures its relying-party trust settings (rpId,rpNameand exactorigins), and they require HTTPS outside local development. Built on@simplewebauthn/serverand@simplewebauthn/browser14.@byline/admin,@byline/db-postgres,@byline/db-mysql: Background cleanup of authentication records. Byline now automatically cleans up expired authentication records in the background, retaining ended sign-in records for 30 days. Three recurring tasks (auth.maintenance.attempts,auth.maintenance.loginsandauth.maintenance.legacy-refresh) are created bycreateAuthMaintenanceTasks(adminStore)from@byline/admin/auth, and run in small, bounded batches so they never hold long locks.@byline/admin,@byline/host-tanstack-start,@byline/ui,@byline/i18n: Admin account and user screens refined. The sign-in page places Sign in with a passkey below an "Or continue with" divider, with a newPasskeyIconin@byline/ui. Adding and renaming a passkey open in a drawer like the other edit panels, while removal stays a confirmation modal; on narrow screens their actions stack full-width. Cancel buttons across the account, user and role forms now use the neutralnoeffectstyle. On the Account page, Appearance is merged into Preferences and the Passkeys card matches the surrounding cards. On the Users screen, user and role cards share the account cards' corner radius, the detail page reads Account Details and Roles, then Password, Passkeys and Delete Admin User, and your own entry keeps the admin passkey view with a link to your Account page.@byline/cli: New installations include passkeys and cleanup. The bundled database baselines now include the passkey tables and cleanup indexes, and the generatedserver.config.tstemplates read theBYLINE_PASSKEY_*variables and register the cleanup tasks.
Chores
- monorepo: Squashed the development Drizzle migrations for PostgreSQL and MySQL into a single baseline each, and synchronised the CLI's bundled copies.
Migrations
@byline/db-postgres,@byline/db-mysql: Apply the passkey upgrade script before starting 6.8.0. Existing installations must applypackages/db-postgres/sql/0014_add-passkeys.sql(PostgreSQL) orpackages/db-mysql/sql/0009_add-passkeys.sql(MySQL), after any earlier scripts they have not yet applied, in filename order. The scripts are not part of the npm packages. Both are safe to re-run, and the PostgreSQL script includes the ownership guard. New installations created withbyline initalready include these changes.@byline/admin: Register the cleanup tasks. Add...createAuthMaintenanceTasks(adminStore)torecurringTasksinbyline/server.config.ts. Upgrading the packages alone does not change an existing application's configuration.@byline/admin,@byline/host-tanstack-start: Enabling passkeys (optional). Follow the updated CLI templates: build apasskeystrust object fromBYLINE_PASSKEY_RP_ID,BYLINE_PASSKEY_RP_NAMEandBYLINE_PASSKEY_ORIGINS(set all of them or none; a partial configuration fails at boot), pass it toJwtSessionProvider, and addpasskeysandpasskeyRequeststo the server config, withcreatePasskeyRequestLimiter(adminStore.signInRateLimits, signingSecret). A passkey belongs to its relying-party ID, so changing the site's domain later invalidates existing passkeys. Grantadmin.users.managePasskeysto the roles that should handle passkey recovery.
Breaking Changes
- monorepo: Node.js
>=22.22.2is now required by every published package and by the CLI's preflight check, because Byline's own toolchain (Vite 8, Vitest 5 and jsdom) needs it. If you run Node 24, use 24.15 or later. Upgrade Node before installing 6.8.0. @byline/admin: CustomAdminStoreimplementations must addpasskeysandauthMaintenance. The built-in PostgreSQL and MySQL adapters provide both. Both are required even when passkeys stay off.@byline/admin,@byline/db-postgres,@byline/db-mysql:refreshTokens.purgeExpired()now deletes only legacy refresh tokens: rows without a login session that expired at least 30 days ago, at most 100 per call. Tokens that belong to a login session are kept until the cleanup task removes the whole ended sign-in, so a replayed old token is still detected as reuse. If you callpurgeExpired()from your own job, expect it to delete fewer rows.
All other @byline/* packages bumped to 6.8.0 in lockstep with no behavioural changes this cycle.