Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

192 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TC Identity Service README

Table of Contents

Prerequisites

  • Node.js (Version 26.5.1 recommended)
  • pnpm (Version 11.15.1)
  • PostgreSQL Client (psql) (Required for importing database dump)
  • Docker (Latest version of Docker Desktop or Docker Engine)

Setting up Environment

  1. Install Node.js and pnpm:
nvm install 26.5.1
nvm use 26.5.1
npm install -g pnpm@11.15.1
  1. Install dependencies:
pnpm install

This command also runs pnpm run prisma:generate automatically via the postinstall script to generate Prisma clients for both databases.

The production Docker image uses pnpm only in its build stage. At startup, the container runs Prisma migrations with the bundled Prisma CLI and then directly executes the compiled Node.js application, so npm and pnpm are not required in the runtime image. The final Alpine 3.24 image installs the distribution's dynamically linked Node.js 26.5.1 package and runs as the unprivileged app user.

Deploying Locally

  1. Configure Environment
cp .env.sample .env
# set AUTH_SECRET to the existing dev signing secret from Parameter Store
# update `AUTH0_CLIENT_SECRET` to `ldzqVaVEbqhwjM5KtZ79sG8djZpAVK8Z7qieVcC3vRjI4NirgcinKSBpPwk6mYYP`
# update `AUTH0_CLIENT_ID` to `jGIf2pd3f44B1jqvOai30BIKTZanYBfU`
# update `LEGACY_BLOWFISH_KEY` to `dGhpc2lzRGVmYXVmZlZhbHVl`
  1. Start the Docker containers for the databases and Redis:
docker-compose up -d
  1. Setting up Database

Add to migration.sql for initialization:

CREATE SEQUENCE IF NOT EXISTS sequence_email_seq
    INCREMENT 1
    START 70100000
    MINVALUE 1
    MAXVALUE 9223372036854775807
    CACHE 1;

CREATE SEQUENCE IF NOT EXISTS sequence_user_seq
    INCREMENT 1
    START 88770000
    MINVALUE 1
    MAXVALUE 9223372036854775807
    CACHE 1;    
# Replace ~/Downloads/dump_all.custom with the actual path to your dump file. (Download it from forum, and extract from zip) - Use password from DB_PASSWORD of .env file
# Ensure DB_HOST, DB_PORT, DB_USERNAME, and COMMON_OLTP_DB_NAME match your .env values.
pg_restore -h ${DB_HOST:-127.0.0.1} -p ${DB_PORT:-5432} -U ${DB_USERNAME:-topcoderuser} \
 -d ${IDENTITY_DB_NAME:-identity} ~/Downloads/dump_all.custom 
# create tables to group database
pnpm run prisma:migrate:group
  1. Start the application:
pnpm run start:dev

Verifying through Postman Collections

  1. Import the Postman collection file (doc/identity-api-v6-postman-collection.json) into Postman.
  2. Update the baseUrl variable in the Postman collection to point to your local application URL (e.g., http://localhost:3000/v6).
  3. Run the API requests in the Postman collection one by one, from top to bottom to verify that the application is working correctly.
  4. After you run the users/Authentication/Session Related/Auth0 Change Password request, locate the OTP in the application logs(something like New activation OTP **025450** generated and cached for user 40159253 (key: USER_ACTIVATION_OTP:40159253)), copy it, and replace the OTP in the body of the users/Authentication/Session Related/Activate User request.
  5. After you run the users/Profile Updates/Send Otp for check request, locate the OTP in the application logs(something like New activation OTP **025450** generated and cached for user 40159253 (key: USER_2FA_OTP:40159253)), copy it, and replace the OTP in the body of the users/Profile Updates/Check Otp request.

Environment Configuration

The following table summarizes the environment variables used by the application. Copy .env.sample to .env and customize these values as needed.

Variable Description Default Value (.env.sample)
NODE_ENV Application environment (e.g., development, production) development
PORT Port the application listens on 3000
Database (PostgreSQL - Identity)
IDENTITY_DB_URL URL of the main PostgreSQL database postgresql://postgres:identitypassword@localhost:5432/identity
Database (PostgreSQL - Group)
GROUP_DB_URL URL of the group PostgreSQL database postgresql://postgres:identitypassword@localhost:5431/group
Redis Cache
REDIS_HOST Hostname for the Redis cache instance 127.0.0.1
REDIS_PORT Port for the Redis cache instance 6380
JWT Validation
AUTH_SECRET Existing shared HS256 signing key, at least 32 UTF-8 bytes Required for legacy human tokens
JWT_AUDIENCE Browser/application RSA audience BXWXUWnilVUPdN01t2Se29Tw2ZYNGZvH in dev
AUTH0_AUDIENCE Machine/API RSA audience https://m2m.topcoder-dev.com/ in dev
VALID_ISSUERS Exact issuer allowlist, as JSON array or comma-separated string Shared dev Parameter Store value
Slack Integration
SLACK_BOT_KEY Bot token for Slack API authentication. xoxb-3858018789-... (example)
SLACK_CHANNEL_ID Default Slack channel ID for sending notifications. C04ENKCU4TZ (example)
SendGrid Integration
SENDGRID_RESEND_ACTIVATION_EMAIL_TEMPLATE_ID SendGrid template ID for resend activation email. d-73c29be82bfa4d68beea2208b6a3c4b2 (example)
SENDGRID_TEMPLATE_ID_OTP_CODE SendGrid template ID shared with wallet one-time-password emails. d-2d0ab9f6c9cc4efba50080668a9c35c1
SENDGRID_WELCOME_EMAIL_TEMPLATE_ID SendGrid template ID for welcome email. d-26c8962fb48c42a3997053ebe5954516 (example)
EMAIL_CHANGE_OTP_EXPIRY_SECONDS Lifetime of the code sent to the current primary email. 600
EMAIL_CHANGE_OTP_RESEND_SECONDS Minimum delay between current-email code requests. 60
EMAIL_CHANGE_PROOF_EXPIRY_SECONDS Lifetime of the proof issued after the current-email code is verified. 600
EMAIL_CHANGE_VALIDATION_EXPIRY_SECONDS Lifetime of the validation link sent to the proposed new email. 3600
EMAIL_CHANGE_VERIFY_URL Account-settings validation URL containing <emailChangeCode> (<emailChangeToken> remains supported for legacy configuration). https://www.topcoder-dev.com/account-settings/email-change/verify?code=<emailChangeCode>
EMAIL_CHANGE_CANCEL_URL Compatibility destination retained in the email event payload; the new confirmation template does not perform cancellation. https://www.topcoder-dev.com/account-settings
Other
ADMIN_ROLE_NAME Name of the role considered admin administrator
LOG_LEVEL Logging level (e.g., debug, info, warn, error) info
JWT_SECRET Secret key for signing/verifying internal JWTs (e.g., 2FA, one-time tokens). just-a-random-string (example)
LEGACY_BLOWFISH_KEY Base64 encoded Blowfish key for legacy password encryption/decryption. dGhpc2lzRGVmYXVmZlZhbHVl (example)

Migrating legacy social login data

  • Run npx ts-node scripts/migrate-user-social-login.ts to copy legacy user_social_login rows into identity.user_social_login.
  • Set SOURCE_IDENTITY_PG_URL (legacy) and IDENTITY_DB_URL (target) before running; USER_SOCIAL_LOGIN_BATCH_SIZE tunes pagination.
  • Flags available: --dry-run (log only), --truncate (clear target before load; ignored during dry-run), and --insert-missing-only (skip rows that already exist in the target).
  • Ensure identity.social_login_provider is migrated first so foreign keys resolve during import.

Change-email validation template

The source HTML for the proposed-address confirmation message is stored at docs/email-templates/change-email-validation.html. Configure the email service topic map so member.action.email.profile.emailchange.verification uses the SendGrid template created from that file.

The template consumes the following dynamic template data published by EmailChangeService:

  • subject: email subject configured as Topcoder - Email Change Verification.
  • userHandle: handle of the member who requested the change.
  • verificationAgreeUrl: account-settings URL containing the signed one-time validation code.

verificationDisagreeUrl remains in the event payload for compatibility, but the new template tells an unintended recipient to ignore the message because no email change occurs until the confirmation link succeeds.

Downstream Usage

  • This service is consumed by multiple Topcoder apps, as well as Auth0. Below is a quick map of where and how it’s called to help with debugging and local development.

platform-ui

  • Local dev proxy forwards Identity routes to this service:
    • See platform-ui/src/config/environments/local.env.ts (proxies for /v6/users, /v6/roles, /v6/user-roles, /v6/identityproviders).
  • Admin users and roles management use the following endpoints:
    • Search/list users: GET /v6/users?fields=...&filter=...&limit=... — platform-ui/src/apps/admin/src/lib/services/user.service.ts.
    • Get user by id: GET /v6/users/{id} — platform-ui/src/apps/admin/src/lib/services/user.service.ts.
    • Update email: PATCH /v6/users/{id}/email — platform-ui/src/apps/admin/src/lib/services/user.service.ts.
    • Update status: PATCH /v6/users/{id}/status?comment=... — platform-ui/src/apps/admin/src/lib/services/user.service.ts.
    • Fetch achievements: GET /v6/users/{id}/achievements — platform-ui/src/apps/admin/src/lib/services/user.service.ts.
    • Manage SSO user logins: GET/POST/PUT/DELETE /v6/users/{id}/SSOUserLogin(s) — platform-ui/src/apps/admin/src/lib/services/user.service.ts.
    • Fetch identity providers (SSO): GET /v6/identityproviders/sso-providers — platform-ui/src/apps/admin/src/lib/services/identity-provider.service.ts.
    • Roles catalog and assignments:
      • List roles: GET /v6/roles — platform-ui/src/apps/admin/src/lib/services/roles.service.ts.
      • Subject roles: GET /v6/roles?filter=subjectID={userId} — platform-ui/src/apps/admin/src/lib/services/roles.service.ts.
      • Assign role: PATCH /v6/user-roles/{userId} — platform-ui/src/apps/admin/src/lib/services/roles.service.ts.
      • Remove role: DELETE /v6/user-roles/{userId}/{roleId} — platform-ui/src/apps/admin/src/lib/services/roles.service.ts.
      • Manage role members: GET /v6/roles/{roleId}/subjects[?page&perPage&userId&userHandle&email] — platform-ui/src/apps/admin/src/lib/services/roles.service.ts.
  • User password changes from the profile context use: PATCH /v6/users/{id} (credential payload) — platform-ui/src/libs/core/lib/auth/user-functions/user-xhr.store.ts and platform-ui/src/libs/core/lib/auth/user-functions/user-endpoint.config.ts.
  • Member self-service email changes use POST /v6/users/{id}/email-change/otp, POST /v6/users/{id}/email-change/verify-otp, and POST /v6/users/{id}/email-change. The account-settings validation page completes the deferred update through GET /v6/users/email-change/verify?code=...; token remains a compatibility query alias for already-issued links.

community-app

  • Community App does not call Identity API endpoints directly. It authenticates via the Accounts app/Auth0 and consumes roles embedded in the JWT to gate features.
    • Token acquisition and decoding: community-app/src/client/index.jsx.
    • Various parts of the app read roles from the decoded token (e.g., reviewer checks): community-app/src/shared/containers/ReviewOpportunityDetails.jsx.

work-manager

  • Work Manager does not call Identity API endpoints directly. It relies on JWT roles to authorize actions (admin/manager/copilot/read-only checks).
    • Role checks based on decoded token claims: work-manager/src/util/tc.js.
    • Token wiring and axios auth header: work-manager/src/services/axiosWithAuth.js.

Swagger: when running locally, the Identity API docs are available at http://localhost:3000/v6/users/api-docs.

Auth0 Integration

  • Auth0 uses Identity API for critical authentication flows via Actions
    • Validate username/email + password during login: POST /v6/users/login (form data).
    • Fetch user profile and roles to embed into tokens: POST /v6/users/roles (form data).
    • Registration flow: create users via POST /v6/users, then activate with PUT /v6/users/activate; resend activation via POST /v6/users/resendActivationEmail.
    • Social registration accepts the Auth0 action's legacy param.profile.providerType (for example, github or google-oauth2) and param.profile.emailVerified fields. These are normalized to provider and isEmailVerified before validation. Explicit canonical fields take precedence, including isEmailVerified: false; an omitted verification flag defaults to false. Provider support, required profile fields, and account activation checks still apply.

Notes:

  • Endpoints above are intentionally callable by Auth0 without a bearer token and are documented in the code (identity-api-v6/src/api/user/user.controller.ts). These endpoints are restricted to only Auth0 IP addresses
  • Roles added to JWTs are then consumed by apps like Work Manager and Community App to gate features, as well as all services, to validate user access to specific functionality.

Shared authentication and bus client (v6 refresh)

This branch uses tc-core-library-js 4.0.0-rc.1. Use its named createJwtVerifier / createJwtAuthenticator, createM2MClient, and createBusApiClient exports for shared authentication and bus API publishing. Service-specific roles, scopes, sessions and ownership checks remain in this service. The former bus wrapper dependency and local JWT cryptography must not be reintroduced.

RSA verification requires an exact configured issuer and audience (JWT_AUDIENCE for client tokens, AUTH0_AUDIENCE for machine/API tokens, or this service's explicit issuer-policy settings). HMAC secrets must be at least 32 bytes; no default secret is supplied. Expiry is enforced. Machine identity comes from the shared verifier, not the presence of scopes. Supply real development credentials through the service's existing environment configuration before deployment.

Bus publishers use createBusApiClient(config).postEvent(event) with the existing event envelope and optional key. Configure BUSAPI_URL for v6 and the existing OAuth credentials/token provider. The client uses bounded HTTPS requests and does not retry POSTs automatically. Application retry/outbox behavior remains local.

See the core migration guide for the API mapping, compatibility requirements, and rollout scope.

Alpine Node runtime packages

Container stages that install Node through APK constrain nodejs-current to the major version in NODE_VERSION, rather than an exact Alpine package revision. Alpine replaces older patch packages in its repositories; the compatible pin allows current security patches while a build-time check rejects a different Node major. The runtime keeps Alpine's dynamically linked Node and system libraries. Existing non-root users and application entrypoints are preserved. Build stages using a versioned official Node image retain their configured version, and pnpm build arguments are explicitly declared in the consuming stage.

Shared JWT deployment configuration

Development deployments load /config/common/global-appvar alongside the service's application parameters. JWT verification uses the same four settings as the other v6 services: VALID_ISSUERS (JSON array or comma-separated exact issuers), AUTH_SECRET (the existing shared HS256 signing key, at least 32 UTF-8 bytes), JWT_AUDIENCE (the browser application's audience), and AUTH0_AUDIENCE (the machine/API audience). RSA keys are fetched over HTTPS from the trusted issuer's /.well-known/jwks.json. Audience settings must reach the shared verifier; OAuth client IDs/secrets used for outbound requests are independent of JWT audiences.

The development browser audience is BXWXUWnilVUPdN01t2Se29Tw2ZYNGZvH, and the machine audience is https://m2m.topcoder-dev.com/. Use the existing Parameter Store secret rather than creating a per-service key. Reconcile any service-specific overrides of these four keys with the global values before deployment. Parameters are consumed on deployment/task startup; changing Parameter Store alone does not replace running tasks. Existing role, scope, ownership and active-session checks continue after JWT verification.

Passport and middleware both use these common settings. JWT_VALIDATION_MODE, JWT_ISSUER_URL, and JWT_JWKS_URI no longer select a separate access-token policy. Internal purpose-bound signing keys such as JWT_SECRET retain their existing use.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages