npm package: @konijima/identity-api
Description: A fully typed, secure Node.js/TypeScript wrapper for the Identity Microservice API. Provides easy backend integration for authentication, session management, 2FA, and more by interacting with your real identity service.
Author: Konijima
Latest version: 1.0.0

# identity-client

A TypeScript/Node.js wrapper for the Identity Microservice API. This package provides a fully typed, backend-focused client for securely integrating with your identity/auth microservice. It handles all request/response typing, error handling, and security best practices, making it easy to call the actual identity service from any Node.js backend (Express, Fastify, etc).

---

## What is this project?

`identity-client` is a backend-only npm package that:

- Wraps all endpoints of your identity microservice (login, registration, 2FA, session management, email change, etc)
- Provides strict TypeScript types for all requests and responses
- Handles token management, 2FA flows, and session tracking
- Is **not** for frontend/browser use—never forward sensitive fields to the client!

---

## API Endpoints (Methods)

### Authentication

- **login({ email, password })**
  - Authenticate a user. Returns access/refresh tokens, or a code indicating 2FA is required.
- **refresh({ refreshToken }, accessToken?)**
  - Refresh the access token using a valid refresh token.
- **logoutSession({ sessionId })**
  - Invalidate a specific session (device/browser).
- **listSessions()**
  - List all active sessions for the current user, including device/IP metadata.

### 2FA (Two-Factor Authentication)

- **toggle2FA({ enable })**
  - Start enabling or disabling 2FA for the current user.
- **confirmEnable2FA({ email, code })**
  - Confirm enabling 2FA with a code sent to the user.
- **confirmLogin2FA({ email, code })**
  - Complete login if 2FA is required (after initial login call).

### User Info

- **me()**
  - Get the current authenticated user's profile and status.

### Email Change

- **requestEmailChange({ newEmail })**
  - Request to change the user's email. Returns a token to send to the new address.
- **confirmEmailChange({ email, token })**
  - Confirm the email change using the token sent to the new address.

---

## Example Usage

### Basic Setup

```ts
import { IdentityClient } from 'identity-client';

const client = new IdentityClient({
  baseUrl: 'http://localhost:3001/api',
  getAuthToken: () => myAccessToken, // Optional: for auto-injecting Authorization
});
```

### Login and 2FA

```ts
const loginRes = await client.login({ email: 'user@example.com', password: 'StrongP@ssw0rd!' });
if (loginRes.code === 'LOGIN_2FA_REQUIRED') {
  // Prompt user for 2FA code, then:
  const confirmRes = await client.confirmLogin2FA({
    email: 'user@example.com',
    code: userInput2FACode,
  });
  // confirmRes contains tokens if successful
}
if (loginRes.token) {
  // Save loginRes.token and loginRes.refreshToken securely (never send to frontend)
}
```

### Get Current User

```ts
const me = await client.me();
console.log(me.email);
```

### Session Management

```ts
const sessions = await client.listSessions();
await client.logoutSession({ sessionId: sessions.sessions[0].sessionId });
```

### Email Change Flow

```ts
const reqRes = await client.requestEmailChange({ newEmail: 'new@example.com' });
// Send reqRes.emailChangeToken to the new email address (never expose to frontend)
const confirmRes = await client.confirmEmailChange({
  email: 'new@example.com',
  token: reqRes.emailChangeToken!,
});
```

### 2FA Enable/Disable

```ts
const enableRes = await client.toggle2FA({ enable: true });
await client.confirmEnable2FA({ email: 'user@example.com', code: enableRes.twoFACode! });
await client.toggle2FA({ enable: false });
```

### Token Refresh

```ts
const refreshRes = await client.refresh({ refreshToken: myRefreshToken }, myAccessToken);
```

---

## Express Server Example

```ts
import express from 'express';
import { IdentityClient } from 'identity-client';

const identityClient = new IdentityClient({
  baseUrl: 'http://localhost:3001/api',
});

const app = express();
app.use(express.json());

// Login route (proxy to identity microservice)
app.post('/api/login', async (req, res) => {
  const { email, password } = req.body;
  const result = await identityClient.login({ email, password });
  // Only forward safe fields to frontend! Never expose refresh tokens, 2FA secrets, or internal metadata.
  res.json({
    token: result.token, // If you use JWTs in frontend
    code: result.code,
    // ...other non-sensitive fields as needed
  });
});

// Authenticated route using access token from client
app.get('/api/me', async (req, res) => {
  const accessToken = req.headers['authorization']?.replace('Bearer ', '');
  const client = new IdentityClient({
    baseUrl: 'http://localhost:3001/api',
    getAuthToken: () => accessToken,
  });
  const me = await client.me();
  res.json(me);
});

// Token refresh
app.post('/api/refresh', async (req, res) => {
  const accessToken = req.headers['authorization']?.replace('Bearer ', '');
  const { refreshToken } = req.body;
  const client = new IdentityClient({
    baseUrl: 'http://localhost:3001/api',
    getAuthToken: () => accessToken,
  });
  const result = await client.refresh({ refreshToken }, accessToken);
  res.json(result);
});

// Email change flow
app.post('/api/request-email-change', async (req, res) => {
  const accessToken = req.headers['authorization']?.replace('Bearer ', '');
  const { newEmail } = req.body;
  const client = new IdentityClient({
    baseUrl: 'http://localhost:3001/api',
    getAuthToken: () => accessToken,
  });
  const result = await client.requestEmailChange({ newEmail });
  // Send result.emailChangeToken to the new email address (never expose to frontend)
  res.json({ status: 'ok' });
});

// ...other routes for 2FA, session management, etc.

app.listen(4000, () => {
  console.log('Backend API running on port 4000');
});
```

---

## Security & Usage Notes

### Authentication
- Never expose access or refresh tokens to the frontend. Use HTTP-only cookies or secure server-side storage.
- Always validate credentials server-side. Do not proxy login directly to the frontend.

### 2FA (Two-Factor Authentication)
- 2FA codes (twoFACode/setupCode) are sensitive and must never be sent to or stored in the frontend.
- Only backend systems should handle 2FA confirmation and enable/disable flows.
- Always require both email and twoFACode for confirmation endpoints.

### Session Management
- Session and device/IP metadata are for backend auditing and security. Never expose session tokens or metadata to the frontend.
- Use `listSessions` and `logoutSession` only in trusted backend contexts.

### Email Address Change
- Email change tokens must only be sent to the new email address, never to the user’s browser or frontend.
- Always confirm email changes server-to-server.

### User Info
- The `me()` endpoint returns the current authenticated user's info. Only expose non-sensitive fields to the frontend.
- Never expose internal user IDs or metadata unless required and safe.

### Token Refresh
- Refresh tokens are highly sensitive. Never send them to the frontend or store them in local/session storage.
- Always use secure, backend-only flows for token refresh.

---

## Build

```bash
npm install
npm run build
```

## Publish

Only the `dist/` directory will be published to npm.