Changelog
Documentation site (2026-08-20)
Docs aligned with SDK 0.14.0: refresh tokens live in a dedicated refreshtokens collection, and host examples now pass that store into authService.
🔄 Changed
Version pins
- Quickstart and the migration guide target
@nodeblocks/backend-sdk@^0.14.0.
Authentication datastores
authServiceexamples pass requiredrefreshtokensalongsideidentitiesin Quickstart, Authentication service, Authentication index, OAuth, Invitation, composite service, WebSocket service, functional programming, and mail-service.- Datastore tables on Authentication service, OAuth, and Invitation list
refreshtokensas required.
Authentication reference
softDeleteRefreshTokensis documented againstrefreshtokensand no longer filters onjti/email.- Authentication routes wire
softDeleteRefreshTokenstodb.refreshtokenson delete-refresh-tokens, complete-password-reset, change-password, and deactivate. - Authentication handlers:
logoutandrefreshTokeninventories userefreshtokensinstead ofidentities.
Identity
getIdentityByIdlooks up{ id }only; thejti: { $exists: false }filter is no longer documented.
SDK 0.14.0 (2026-08-19)
✨ Added
Authentication
- Require a dedicated
refreshtokenscollection onAuthenticationServiceDataStore. Login, logout, refresh rotation, admin token deletion, and bulk revoke (softDeleteRefreshTokens) all persist refresh tokens there instead of inidentities.
🔄 Changed
Authentication
createRefreshToken,logout,refreshToken, anddeleteTokennow read and writedb.refreshtokens.softDeleteRefreshTokensis wired torefreshtokensfrom password-reset, change-password, deactivate, and delete-refresh-tokens routes, and no longer filters onemail/jti(those discriminators were only needed while tokens shared theidentitiescollection).
Identity
getIdentityByIdno longer appliesjti: { $exists: false }when looking up an identity.
📦 Migration
- Auth hosts: Pass a
refreshtokensMongoDB collection intoauthService(and any custom composition that previously useddb.identitiesfor refresh tokens). The field is required — missing wiring fails at compile time. - Existing sessions: After upgrade, refresh / logout / bulk revoke only look at
refreshtokens. Rows still inidentities({ jti: { $exists: true } }) will not refresh or revoke. Copy them intorefreshtokensif sessions should survive, then delete them fromidentitieseither way so identity lookups cannot hit a leftover token document. - Indexes: Create a unique index on
refreshtokens.jtiin the host database. The SDK does not create indexes.
⚠️ Breaking Changes
- Authentication:
AuthenticationServiceDataStore.refreshtokensis required. Hosts that omit it will not type-check, and runtime token writes will fail. - Authentication: Refresh tokens are no longer stored in
identities. Existing token documents in that collection are ignored until migrated (see Migration).
SDK 0.13.0 (2026-07-14)
✨ Added
Services
- Optional
authMode?: 'bearer' | 'cookie'on protected CRUD / domain service configurations (attributes, profile, product, category, organization, location, order, chat, identity, notification, address). WhenauthModeis'cookie', each service wiresgetCookieTokenInfointocontext.authenticate; otherwise it usesgetBearerTokenInfo. See Authentication service and mountable domain integration guides.
Authentication
checkIp?: boolean(defaulttrue) onAuthenticationServiceConfiguration; bothgetBearerTokenInfoandgetCookieTokenInfohonor this option. See Authentication service.whenCookieAuthutility (exported from utils) branches a composed handler between cookie-mode and bearer-mode implementations based onauthMode.context.authenticatetyped field onServiceContext/ServiceDefinition, populated withgetCookieTokenInfoorgetBearerTokenInfodepending onauthMode.- Standalone
logoutFeature, selectinglogoutCookieSchemaorlogoutBearerSchemaat compose time based onauthMode. refreshTokenBearerSchemaandrefreshTokenCookieSchema;refreshTokenSchemaremains as a deprecated alias forrefreshTokenBearerSchema.cookieOpts.httpOnlyandcookieOpts.secureare now configurable (previously hard-coded totrue).
🔄 Changed
Authentication
- Session cookie
maxAgeis derived automatically from each token'sexpiresIn(accessTokenSignOptions/refreshTokenSignOptions) when cookies are set, so the cookie and token always expire together. loginWithCredentialsRoute: cookie mode returns only{ id }in the response body; tokens are delivered viaSet-Cookie. Bearer mode is unchanged ({ accessToken, id, refreshToken }).refreshTokenRoute: cookie mode sets refreshed cookies and returns 204 with an empty body; bearer mode is unchanged (200 { accessToken, refreshToken }).setResponseCookiederives access-token and refresh-token cookie options independently fromaccessTokenSignOptions.expiresIn/refreshTokenSignOptions.expiresIn, instead of sharing a single set of options.
🐞 Fixed
Authentication
logoutRoute: clearsaccessTokenandrefreshTokencookies unconditionally, instead of only when a refreshToken cookie was present on the request; resolves the caller's identity viacontext.authenticate(cookie- or bearer-aware); treats an already-revoked refresh token as success instead of error; returns success when no refresh token can be resolved instead of error.deactivateRoute: reads the access token from theaccessTokencookie in cookie mode instead of always requiring anAuthorizationheader.
Organization
createChangeRequestRoute: reads the access token from theaccessTokencookie in cookie mode instead of always requiring anAuthorizationheader.
🔒 Security
- Removed an undocumented bypass in
getCookieTokenInfothat accepted an app-typeAuthorization: Bearertoken to skip cookie/session validation entirely. getCookieTokenInfono longer hard-codescheckIp: false; cookie-authenticated user tokens are IP-checked by default like bearer tokens.
📦 Migration
- Cookie auth hosts: Setting authMode: 'cookie' on authentication alone is not enough. Pass authMode: 'cookie' on every mounted protected service that must accept cookie sessions, and register cookie-parser middleware.
- Cookie-mode clients: Read access/refresh tokens from Set-Cookie response headers on POST /auth/login and POST /auth/token/refresh; they are no longer present in the response body.
- Manual loginWithCredentialsFeature compositions: Add logoutFeature explicitly to keep POST /auth/logout (the authService factory already does this automatically).
- Access token lifetime: If you relied on the default 2h access token lifetime, set
accessTokenSignOptions: { expiresIn: '2h' }explicitly — the default is now 15m. - Cookie auth IP checks: If your deployment's client IP can legitimately change between requests (e.g. some proxies or mobile networks), set checkIp: false explicitly in AuthenticationServiceConfiguration.
- Removed validators: Replace any direct imports of validateResourceAccess, validateOrganizationAccess, validateOrderAccess, validateMessageAccess, validateChannelAccess, verifyAuthentication, requireParam, isUUID, or isNumber with their current equivalents (isAuthenticated, hasOrgRole, ownsResource, ownsOrder, ownsMessage, ownsChannel, etc.).
⚠️ Breaking Changes
- Authentication:
AuthenticationServiceConfiguration.cookieOpts.maxAgehas been removed. Cookie lifetime follows the matching token'sexpiresIn. Remove anycookieOpts.maxAgeconfiguration. - Authentication: Default
accessTokenSignOptions.expiresInchanged from2hto15m. - Authentication:
loginWithCredentialsFeatureno longer composeslogoutRoute. Custom compositions built directly onloginWithCredentialsFeature(outsideauthService) must addlogoutFeatureseparately. - Authentication: Cookie-mode login and refresh no longer return tokens in the response body.
- Authentication:
getCookieTokenInfono longer acceptsAuthorization: Beareras a bypass path for cookie auth. - Validators: Removed unused legacy validator exports from Common validators:
validateResourceAccess,validateOrganizationAccess,validateOrderAccess,validateMessageAccess,validateChannelAccess,verifyAuthentication,requireParam,isUUID, andisNumber.
SDK 0.12.0 (2026-07-07)
🐞 Fixed
Authentication
completePasswordResetRoute: revokes all active refresh tokens when a user resets their password to invalidate existing sessions across all devices.changePasswordRoute: revokes all active refresh tokens when a user changes their password.- Fingerprint security check:
tokenPassesSecurityChecktreatsundefinedand''as equivalent; token generation normalizes fingerprint to''at generation time. logoutRoute: clears auth token cookies only when refresh token revocation succeeds.
🔄 Changed
Authentication
softDeleteRefreshTokenssetsdeletedAtinstead ofdelFlgto align with refresh token revocation checks.refreshTokenRoute: rotates refresh tokens on each use (newjti+ DB row); returns 401 on reuse of a revoked refresh token without revoking other device sessions; usesresolveRefreshTokenFromRequestfor cookie/body resolution.logoutRoute: revokes the presented refresh token (cookie or body) after verifying it belongs to the authenticated identity.- Cookie-based refresh reads fingerprint from the
x-nb-fingerprintheader (same as body path) and runs IP/UA checks. See cookie utility.
⚠️ Breaking Changes
- Cookie-based refresh (
refreshTokenRoute) and cookie-based logout (logoutRoute) require thex-nb-fingerprintheader.request.body.fingerprintis no longer read on the cookie path.
SDK 0.11.0 (2026-05-26)
✨ Added
Combinators
mapMatchingErrorToFalse: maps only a specific matched error class took(false), replacing the previousmapErrorToFalsewhich converted all errors.
🔄 Changed
Profile (formerly User)
- Renamed user handlers, blocks, routes, schemas, features, and service to profile. See Profile service and Profile blocks.
- Updated
userscollection references toprofilesin organization and product routes and services. - Removed deprecated
validateUserProfileAccessvalidator. - Updated return type for
getProfileById.
🔒 Security
Change Email
changeEmailRoute: returns 204 instead of an error when the requested email address is already in use, preventing email enumeration.- Uses
mapMatchingErrorToFalseto convert only conflict errors took(false).
⚠️ Breaking Changes
- Profile rename:
userservice, routes, blocks, schemas, and features are renamed toprofile. Update all imports fromuser*toprofile*. - Validators:
validateUserProfileAccesshas been removed. Use the updated Profile validators instead. - Combinators:
mapErrorToFalseis renamed tomapMatchingErrorToFalseand requires an error class as the first argument.
SDK 0.10.0 (2026-03-17)
✨ Added
Notification Management
- New service: Notification service.
- New endpoints:
GET /notifications/identities/:identityId— find notifications with pagination. See Notification routes.POST /notifications/:notificationId/read— mark a single notification as read.POST /notifications/identities/:identityId/read— batch mark as read up to an anchor notification.
- Notification blocks for create, bulk create, find, get, single update, and batch update operations.
Address Lookup
- New service: Address service with Japan Post driver.
- New endpoint:
GET /addresses— find a Japanese address by postal code. See Address routes. - Reusable in-memory LRU cache utility for address lookup results.
Organization Member Protection
- Validators to prevent removing the last owner from an organization.
- Role-assignment validation so members cannot assign roles above their own rank.
- Same-or-above role validation before deleting organization members. See Organization validators.
🐞 Fixed
Identity
getIdentityRoute: prevents matching token records stored in the identities collection by excluding documents withjti.
Address Lookup
- Japan Post postal code handling requires a full 7-digit code at lookup time.
- Returns
nullfor ambiguous town names instead of guessing when multiple towns share the same postal code.
🔄 Changed
Authentication Configuration
- Replace string-based expiration settings with
accessTokenSignOptions,refreshTokenSignOptions, andonetimeTokenSignOptions. See Authentication service and auth utility. - Apply shared one-time token signing options across password reset, email change, MFA, and OAuth flows.
Authorization Rules
- Strengthen organization member upsert and delete routes with additional role hierarchy checks.
SDK 0.9.1 (2026-01-22)
✨ Added
Authentication
- Password validation to check new password is not the same as the current password.
- Separate bcrypt compare and matches logic into two blocks; new
assertDoesNotMatchblock for password-must-not-match flows.
Schema Validation
- Handle type-less schemas with object-related keywords in
applySchemaDefaults. - Support for union types including
objectin schema validation.
🔄 Changed
- Enhanced OpenAPI schema generation with improved tag propagation and nullable schema support.
🔒 Security
- MongoDB query filter validation for NoSQL injection protection. See schema utilities and Schema component (
queryFilterhardening).
SDK 0.9.0 (2025-11-04)
✨ Added
Location Management
- New service: Location service.
- New endpoints:
POST /locations,GET /locations/:locationId,PATCH /locations/:locationId,DELETE /locations/:locationId,GET /locations. See Location routes. - Parent-child relationship handling with automatic ancestors calculation.
Profile Follow System
- New endpoints:
PUT /profiles/:profileId/profile-follows/:followProfileId— create profile follow. See Profile routes.DELETE /profiles/:profileId/profile-follows/:followProfileId— delete profile follow.GET /profiles/:profileId/followers— get profile followers with pagination.
Organization Follow System
- New endpoints:
PUT /profiles/:profileId/organization-follows/:followOrganizationId— create organization follow.DELETE /profiles/:profileId/organization-follows/:followOrganizationId— delete organization follow.GET /organizations/:organizationId/followers— get organization followers. See Organization routes.
Product Like System
- New endpoints:
PUT /profiles/:profileId/product-likes/:likeProductId— create product like.DELETE /profiles/:profileId/product-likes/:likeProductId— delete product like.GET /products/:productId/likers— get product likers. See Product routes.
Chat Message Template Management
- New endpoints:
GET /message-templates—findChatMessageTemplatesRoute.GET /organizations/:organizationId/message-templates—findChatMessageTemplatesForOrganizationRoute.PATCH /message-templates/:messageTemplateId—updateChatMessageTemplateRoute.DELETE /message-templates/:messageTemplateId—deleteChatMessageTemplateRoute.
Product Variant Bulk Operations
- New endpoints:
POST /products/:productId/variants/bulk,PATCH /products/:productId/variants/bulk,DELETE /products/:productId/variants/bulk,GET /products/:productId/variants. See Product routes.
Find Endpoints
GET /profiles/identities/:identityId— find profiles by identity ID.GET /organizations/:organizationId/orders— find orders by organization ID.GET /organizations/:organizationId/products— find products by organization ID.
Identity Lock/Unlock
- New endpoints:
POST /identities/:identityId/lock—lockIdentityRoute.POST /identities/:identityId/unlock—unlockIdentityRoute.
Chat Channel Icon Management
- New endpoint:
GET /channels/:channelId/icon-upload-url—getChatChannelIconUploadUrlRoute.
Soft Delete
withSoftDeletecombinator for MongoDB collections with automatic filtering and audit trail.
🐞 Fixed
- Add missing
updatedAt/createdAttimestamps to all create and update operations. - Cast IDs to strings in all database queries for security.
🔄 Changed
- Chat message updates restricted to message owners only (admin override removed). See
updateChatMessageRoute. - Entity creation simplified: messages and products created without attachments/images; attachments managed via dedicated endpoints.
SDK 0.8.0 (2025-09-24)
✨ Added
Product Variant Management
- New endpoints:
POST /products/:productId/variants— create product variant.GET /products/:productId/variants/:productVariantId— get product variant by ID.PATCH /products/:productId/variants/:productVariantId— update product variant.DELETE /products/:productId/variants/:productVariantId— delete product variant.
- See Product features and Product routes.
Organization Change Request System
- New endpoints:
createChangeRequestRoute:POST /organizations/:organizationId/change-requests.findChangeRequestsForOrganizationRoute:GET /organizations/:organizationId/change-requests.
Organization Management
updateOrganizationAsAdminRoute:PATCH /admin/organizations/:organizationId/.- Certificate image URL added to normalized organization responses.
Multi-Factor Authentication (MFA)
- New endpoints:
resendMfaCodeRoute:POST /auth/mfa/resend.verifyMfaCodeRoute:POST /auth/mfa/verify.
- MFA enabled via
isMfaEnabled: truein service configuration. See Authentication features.
One-Time Token (OTT) Authentication
loginWithOnetimeTokenRoute:POST /auth/ott/login.- OAuth callback flow returns one-time tokens; frontend exchanges via OTT login endpoint.
Pagination System
- Restructured
PaginationResult<T>to separate data and metadata. - List endpoints return
{ data, metadata: { pagination } }instead of legacy{ count, total, value }. paginationQueryParametersSchemaandpaginationSchemafor standard query parameters and metadata.findOrganizationMembersRoute: embedded pagination viawithPaginatedProperty.
🐞 Fixed
- WebSocket IP address availability in WebSocket requests.
- Pagination metadata return issues.
SDK 0.7.0 (2025-09-12)
✨ Added
Chat Message Attachments
- New endpoints:
createChatMessageAttachmentRoute:POST /messages/:messageId/attachments.deleteChatMessageAttachmentRoute:DELETE /messages/:messageId/attachments/:attachmentId.getChatMessageAttachmentUploadUrlRoute:GET /messages/:messageId/attachment-upload-url.
Chat Channel Messages
getChannelMessagesRoute:GET /channels/:channelId/messages.
Chat Read Receipts
upsertChatChannelReadStateRoute:PUT /channels/:channelId/read-state.
Chat WebSocket Subscription
streamChatMessagesRoute: WebSocket/messages/listenfor real-time message streaming.
LINE OAuth Authentication
- New endpoints:
lineOAuthRoute:GET /auth/oauth/line.lineOAuthCallbackRoute:GET /auth/oauth/line/callback.
Product Image Management
- New endpoints:
POST /products/:productId/images— create product images.DELETE /products/:productId/images/:imageId— delete product image.
- See Product routes.
Blocks
- Chat read-state blocks:
createChatChannelReadState,updateChatChannelReadState,findChatChannelReadStates, and query/payload builders. - Chat message blocks:
createChatMessage,getChatMessageById, attachment CRUD, and normalization helpers. - Product blocks:
getProductById,findProducts, image normalization helpers. - OAuth blocks:
requestLineOAuth,authenticateLineOAuth,verifyLineOAuth. normalizeFile: centralized file normalization utility.
🔄 Changed
- Chat and product normalization refactored to use centralized
normalizeFileutility. - Entity creation simplified: core messages and products created without attachments/images; attachments managed via dedicated endpoints.
🐞 Fixed
- Chat attachment normalization in update responses; security ID casting; admin access restrictions for attachment operations.
- OAuth: Google and Twitter flows fixed to use provider/providerId instead of email workarounds.
SDK 0.6.0 (2025-08-28)
🎥 Demo Video
📹 NodeBlocks Backend SDK v0.6.0 Demo — Complete walkthrough of all new features and functionality.
✨ Added
Chat Message Template System
- New endpoints:
createChatMessageTemplateRoute:POST /message-templates.getChatMessageTemplateRoute:GET /message-templates/:messageTemplateId.
- Blocks:
createChatMessageTemplate,getChatMessageTemplateById. - Features:
createChatMessageTemplateFeature,getChatMessageTemplateFeature. - Schemas:
createChatMessageTemplateSchema. - Validators:
hasOrganizationAccessToMessageTemplate.
Twitter OAuth Authentication
- New endpoints:
twitterOAuthRoute:GET /auth/oauth/twitter.twitterOAuthCallbackRoute:GET /auth/oauth/twitter/callback.
- Drivers:
createTwitterOAuthDriver,verifyTwitterCallback.
Refresh Token System
- New endpoints:
refreshTokenRoute:POST /auth/token/refresh.deleteRefreshTokensRoute:DELETE /auth/:identityId/refresh-tokens.
WebSocket Support with RxJS
- Enhanced
defServiceto support WebSocket server integration. - WebSocket route handling with RxJS bridging;
protocol: 'ws'routes alongside HTTP routes. notFromEmitterandmarkAsFromEmitterfor emitter-based message filtering.
🔄 Changed
Services
- Authentication service: added Twitter OAuth support and refresh token functionality; updated datastore to include
chatMessageTemplatescollection.
🐞 Fixed
- Organization blocks export issue.
refreshTokenRoute: removedisAuthenticatedvalidator from refresh flow.- Configuration property names corrected (
user.typeIds→identity.typeIds;user?: string→regular?: string).
Migration guide (upgrading from 0.6.x docs)
- Install
@nodeblocks/backend-sdk@^0.14.0and follow the Quickstart. - Replace
userService,/users, anduserscollection examples withprofileService,/profiles, andprofiles. - Replace flat token expiry keys with
accessTokenSignOptions,refreshTokenSignOptions, andonetimeTokenSignOptions. SetaccessTokenSignOptions: { expiresIn: '2h' }explicitly if you still need a 2h access token. - For cookie sessions, set
authMode: 'cookie'on Authentication and every protected service you mount, registercookie-parserbefore those routers, and read tokens fromSet-Cookieon login/refresh—not from JSON bodies. - Replace removed validator imports (
validateResourceAccess,verifyAuthentication,requireParam, and similar) with current exports documented under Common validators and domain validator pages. - Use the block catalogue and domain Reference map tables to find the current route, schema, and validator contracts for each endpoint.
- Send the
x-nb-fingerprintheader on cookie-mode refresh and logout requests (SDK 0.12.0). - Add
logoutFeatureto custom compositions built onloginWithCredentialsFeatureoutsideauthService(SDK 0.13.0). - Remove
cookieOpts.maxAge; cookie lifetime follows the matching tokenexpiresIn(SDK 0.13.0). - Replace
mapErrorToFalsewithmapMatchingErrorToFalse(errorClass, [...])(SDK 0.11.0); see composition utilities. - Pass a
refreshtokensMongoDB collection intoauthService(and any custom composition that previously useddb.identitiesfor refresh tokens). The field is required — missing wiring fails at compile time. (SDK 0.14.0).
Breaking documentation changes
- Versioned snapshots under
backend_versioned_docs/version-0.6.0andversion-0.7.0remain historical references. New integrations should use canary v2 docs at/v2/backend/next. - Examples no longer show flat SDK imports,
user*service names, or legacy pagination envelopes. - Cookie-mode login and refresh examples no longer return access or refresh tokens in response bodies; clients must use session cookies instead.
Security documentation updates
- Cookie auth no longer documents an undocumented Bearer bypass on cookie-protected routes; IP checking defaults to enabled via
checkIpunless explicitly disabled. See Authentication service. - Change-email responses document 204 instead of conflict errors to reduce email enumeration; see Authentication routes.
- Organization member protection, notification ownership, and address lookup validation are documented with current access rules on their respective validators and routes pages.