Skip to main content
Version: 🚧 Canary

👥 Profile

The Profile service manages profile records, avatars, profile follows, organization follows, and product likes through authenticated HTTP routes.

Start here

Mount services.profileService with the four collections it reads and writes. JSON request bodies require the host application's express.json() middleware; cookie transport also requires cookie-parser before this router.

import express from 'express';
import cookieParser from 'cookie-parser';
import { services } from '@nodeblocks/backend-sdk';

const app = express();
app.use(express.json());
app.use(cookieParser()); // Required only when `authMode` is 'cookie'.
app.use(
'/api',
services.profileService(
{ identities, profiles, organizations, products },
{
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET!,
authSignSecret: process.env.AUTH_SIGN_SECRET!,
},
authMode: 'bearer',
},
{ fileStorageDriver },
),
);
ConfigurationDefault / source behaviorEffect
authSecrets.authEncSecretRequired; passed to route contextAuthentication utility configuration.
authSecrets.authSignSecretRequired; passed to route contextAuthentication utility configuration.
authModeOmitted or 'bearer' selects getBearerTokenInfoProtected routes read the Bearer token.
authMode: 'cookie'Selects getCookieTokenInfo when setProtected routes read the access-token cookie; cookie-parser is required.
identity.typeIdsRead by administrator checks when suppliedEnables configured admin identity-type comparison.

Common tasks

TaskStart withContract
Create or update a profilecreateProfileFeaturecreateProfileFeature, updateProfileSchema, and updateProfileRoute
Read a profile, its followers, or profiles for the caller identitygetProfileRoutegetProfileRoute, getProfileFollowersRoute, and findProfilesByIdentityIdRoute
Obtain an avatar upload URLgetAvatarUploadUrlFeaturegetAvatarUploadUrlFeature, getSignedImageUploadUrlSchema, and getAvatarUploadUrlRoute
Manage follow and like relationshipsProfile blocksProfile blocks, routes, and schemas
Compose individual endpointscreateProfileFeatureProfile features and the custom composition below

Bearer HTTP workflow

With authMode omitted or set to 'bearer', send a bearer token. This protected update is allowed to an administrator or the profile owner.

PROFILE_ID='profile-demo-001'
ACCESS_TOKEN='replace-with-a-valid-access-token'
curl -X PATCH "https://api.example.test/api/profiles/$PROFILE_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"name":"Example profile"}'

On success, the route returns the normalized profile with no explicit status descriptor. A caller must be an administrator or own PROFILE_ID; a missing profile maps to 404, and a file-storage failure maps to 500. See updateProfileSchema, updateProfileRoute, and Profile validators.

With authMode: 'cookie', register cookie-parser and send the accessToken cookie instead of the Authorization header. The same administrator-or-owner rule applies.

PROFILE_ID='profile-demo-001'
ACCESS_TOKEN='replace-with-a-valid-access-token'
curl -X PATCH "https://api.example.test/api/profiles/$PROFILE_ID" \
-H "Cookie: accessToken=$ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"name":"Example profile"}'

The successful response is the normalized profile without an explicit status descriptor. If the cookie is absent, cookie authentication throws 401; see updateProfileRoute and Profile validators.

Custom feature composition

This composition is a fragment: it needs the same datastore, configuration, authentication, and optional file-storage context that profileService supplies before it is mounted.

import { partial } from 'ramda';
import { features, primitives, utils } from '@nodeblocks/backend-sdk';

const profileFeatureComposer = primitives.compose(features.createProfileFeature);
const profileRouter = primitives.defService(
partial(profileFeatureComposer, [{
authenticate: utils.getBearerTokenInfo,
configuration: { authSecrets },
dataStores: { identities, profiles, organizations, products },
fileStorageDriver,
}]),
);

app.use('/api', profileRouter);

Reference map

PagePurpose
BlocksReusable profile operations and errors.
FeaturesSchema-to-route composers.
HandlersLegacy route-pipeline operations.
RoutesPublic endpoint matrix.
SchemasRequest and stored-shape contracts.
ValidatorsAuthentication and ownership guards.

Avatar supplies avatar schemas and normalizers. Identity supplies identity lookup and type checks. Organization and Product supply the followed and liked resources. Common validators supplies the shared guards, and File storage supplies signed-upload, normalization, and deletion behavior.