2069 lines
66 KiB
YAML
2069 lines
66 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Insforge Authentication API
|
|
version: 2.0.0
|
|
description: Authentication endpoints with separated auth and profile tables
|
|
|
|
paths:
|
|
/api/auth/public-config:
|
|
get:
|
|
summary: Get public authentication configuration
|
|
description: Get all public authentication configuration including OAuth providers and email auth settings (public endpoint)
|
|
tags:
|
|
- Client
|
|
responses:
|
|
'200':
|
|
description: Public authentication configuration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
oAuthProviders:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
customOAuthProviders:
|
|
type: array
|
|
items:
|
|
type: string
|
|
requireEmailVerification:
|
|
type: boolean
|
|
passwordMinLength:
|
|
type: integer
|
|
minimum: 4
|
|
maximum: 128
|
|
requireNumber:
|
|
type: boolean
|
|
requireLowercase:
|
|
type: boolean
|
|
requireUppercase:
|
|
type: boolean
|
|
requireSpecialChar:
|
|
type: boolean
|
|
verifyEmailMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
description: Method for email verification (code = 6-digit OTP, link = magic link)
|
|
resetPasswordMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
description: Method for password reset (code = 6-digit OTP + exchange flow, link = magic link)
|
|
disableSignup:
|
|
type: boolean
|
|
description: When true, new user sign-ups are disabled. Existing users can still sign in.
|
|
|
|
/api/auth/profiles/current:
|
|
patch:
|
|
summary: Update current user's profile
|
|
description: Update the profile of the currently authenticated user
|
|
tags:
|
|
- Client
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- profile
|
|
properties:
|
|
profile:
|
|
type: object
|
|
additionalProperties: true
|
|
description: Profile data (name, avatar_url, and any custom fields)
|
|
properties:
|
|
name:
|
|
type: string
|
|
avatar_url:
|
|
type: string
|
|
format: uri
|
|
responses:
|
|
'200':
|
|
description: Profile updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProfileResponse'
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Unauthorized - authentication required
|
|
|
|
/api/auth/profiles/{userId}:
|
|
get:
|
|
summary: Get user profile by ID
|
|
description: Get public profile information for a user by their ID (public endpoint)
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: userId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: User ID
|
|
responses:
|
|
'200':
|
|
description: User profile
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProfileResponse'
|
|
'400':
|
|
description: Invalid user ID format
|
|
'404':
|
|
description: User not found
|
|
|
|
/api/auth/config:
|
|
get:
|
|
summary: Get authentication configuration
|
|
description: Get current authentication settings including all configuration options (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Authentication configuration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
requireEmailVerification:
|
|
type: boolean
|
|
passwordMinLength:
|
|
type: integer
|
|
minimum: 4
|
|
maximum: 128
|
|
requireNumber:
|
|
type: boolean
|
|
requireLowercase:
|
|
type: boolean
|
|
requireUppercase:
|
|
type: boolean
|
|
requireSpecialChar:
|
|
type: boolean
|
|
verifyEmailMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
description: Method for email verification (code = 6-digit OTP, link = magic link)
|
|
resetPasswordMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
description: Method for password reset (code = 6-digit OTP + exchange flow, link = magic link)
|
|
allowedRedirectUrls:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: List of allowed URLs for authentication redirects. If empty, all redirects are allowed for smoother development UX. This is not recommended in production.
|
|
disableSignup:
|
|
type: boolean
|
|
description: When true, public sign-up endpoints (POST /api/auth/users and first-time OAuth) are rejected with 403 AUTH_SIGNUP_DISABLED. Admin-authenticated user creation is unaffected.
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
put:
|
|
summary: Update authentication configuration
|
|
description: Update authentication settings (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
requireEmailVerification:
|
|
type: boolean
|
|
passwordMinLength:
|
|
type: integer
|
|
minimum: 4
|
|
maximum: 128
|
|
requireNumber:
|
|
type: boolean
|
|
requireLowercase:
|
|
type: boolean
|
|
requireUppercase:
|
|
type: boolean
|
|
requireSpecialChar:
|
|
type: boolean
|
|
verifyEmailMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
description: Method for email verification (code = 6-digit OTP, link = magic link)
|
|
resetPasswordMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
description: Method for password reset (code = 6-digit OTP + exchange flow, link = magic link)
|
|
allowedRedirectUrls:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: List of allowed URLs for authentication redirects. If empty, all redirects are allowed for smoother development UX. This is not recommended in production.
|
|
disableSignup:
|
|
type: boolean
|
|
description: When true, public sign-up endpoints (POST /api/auth/users and first-time OAuth) are rejected with 403 AUTH_SIGNUP_DISABLED. Admin-authenticated user creation is unaffected.
|
|
responses:
|
|
'200':
|
|
description: Configuration updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
requireEmailVerification:
|
|
type: boolean
|
|
passwordMinLength:
|
|
type: integer
|
|
minimum: 4
|
|
maximum: 128
|
|
requireNumber:
|
|
type: boolean
|
|
requireLowercase:
|
|
type: boolean
|
|
requireUppercase:
|
|
type: boolean
|
|
requireSpecialChar:
|
|
type: boolean
|
|
verifyEmailMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
resetPasswordMethod:
|
|
type: string
|
|
enum: [code, link]
|
|
allowedRedirectUrls:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: List of allowed URLs for authentication redirects. If empty, all redirects are allowed for smoother development UX. This is not recommended in production.
|
|
disableSignup:
|
|
type: boolean
|
|
description: When true, public sign-up endpoints (POST /api/auth/users and first-time OAuth) are rejected with 403 AUTH_SIGNUP_DISABLED. Admin-authenticated user creation is unaffected.
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
/api/auth/users:
|
|
post:
|
|
summary: Register new user
|
|
description: Creates a new user account
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: client_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [web, mobile, desktop, server]
|
|
default: web
|
|
description: |
|
|
Client type determines how refresh tokens are returned:
|
|
- web: Refresh token stored in httpOnly cookie, csrfToken returned in response
|
|
- mobile/desktop/server: refreshToken returned directly in response body
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- email
|
|
- password
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: user@example.com
|
|
password:
|
|
type: string
|
|
description: Password meeting configured requirements (check /api/auth/email/config for current requirements)
|
|
example: securepassword123
|
|
name:
|
|
type: string
|
|
example: John Doe
|
|
redirectTo:
|
|
type: string
|
|
format: uri
|
|
description: >-
|
|
Used for link-based email verification. The email link always
|
|
opens an InsForge backend endpoint first; after the token is
|
|
verified, InsForge redirects the browser to this URL. This URL
|
|
must be included in allowedRedirectUrls. Recommended: use your
|
|
app's sign-in page.
|
|
responses:
|
|
'200':
|
|
description: User created successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
user:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
accessToken:
|
|
type: string
|
|
nullable: true
|
|
description: JWT authentication token (null if email verification required)
|
|
csrfToken:
|
|
type: string
|
|
nullable: true
|
|
description: CSRF token for use with refresh endpoint (web clients only, null if email verification required)
|
|
refreshToken:
|
|
type: string
|
|
nullable: true
|
|
description: Refresh token for mobile/desktop/server clients (null for web clients or if email verification required)
|
|
requireEmailVerification:
|
|
type: boolean
|
|
description: Whether email verification is required before login
|
|
'400':
|
|
description: Invalid request
|
|
'403':
|
|
description: Signups disabled — project has disabled new user registration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: AUTH_SIGNUP_DISABLED
|
|
message: User signups are disabled for this project.
|
|
statusCode: 403
|
|
'409':
|
|
description: User already exists
|
|
|
|
get:
|
|
summary: List all users (admin only)
|
|
description: Returns paginated list of users
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: offset
|
|
in: query
|
|
schema:
|
|
type: string
|
|
default: '0'
|
|
description: Number of records to skip
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: string
|
|
default: '10'
|
|
description: Maximum number of records to return
|
|
- name: search
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Search by email or name
|
|
responses:
|
|
'200':
|
|
description: List of users
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
pagination:
|
|
type: object
|
|
properties:
|
|
offset:
|
|
type: integer
|
|
limit:
|
|
type: integer
|
|
total:
|
|
type: integer
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
delete:
|
|
summary: Delete users (admin only)
|
|
description: Delete multiple users by their IDs
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
userIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
required:
|
|
- userIds
|
|
responses:
|
|
'200':
|
|
description: Users deleted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
deletedCount:
|
|
type: integer
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
/api/auth/users/{userId}:
|
|
get:
|
|
summary: Get specific user
|
|
description: Get user details by ID (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: userId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: User ID
|
|
responses:
|
|
'200':
|
|
description: User details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
'400':
|
|
description: Invalid user ID format
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: User not found
|
|
|
|
/api/auth/sessions:
|
|
post:
|
|
summary: User login
|
|
description: Authenticates user and returns access token. For web clients, sets httpOnly refresh token cookie. For mobile/desktop/server clients, returns refreshToken in response body.
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: client_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [web, mobile, desktop, server]
|
|
default: web
|
|
description: |
|
|
Client type determines how refresh tokens are returned:
|
|
- web: Refresh token stored in httpOnly cookie, csrfToken returned in response
|
|
- mobile/desktop/server: refreshToken returned directly in response body
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- email
|
|
- password
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
password:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Login successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
user:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
accessToken:
|
|
type: string
|
|
csrfToken:
|
|
type: string
|
|
nullable: true
|
|
description: CSRF token for use with refresh endpoint (web clients only)
|
|
refreshToken:
|
|
type: string
|
|
nullable: true
|
|
description: Refresh token for mobile/desktop/server clients (null for web clients)
|
|
'401':
|
|
description: Invalid credentials
|
|
'403':
|
|
description: Email verification required
|
|
|
|
/api/auth/refresh:
|
|
post:
|
|
summary: Refresh access token
|
|
description: |
|
|
Refresh access token using refresh token.
|
|
- Web clients: Use httpOnly refresh token cookie with X-CSRF-Token header
|
|
- Mobile/Desktop/Server clients: Send refreshToken in request body
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: client_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [web, mobile, desktop, server]
|
|
default: web
|
|
description: |
|
|
Client type determines how refresh tokens are handled:
|
|
- web: Refresh token from httpOnly cookie, requires X-CSRF-Token header
|
|
- mobile/desktop/server: refreshToken provided in request body, new refreshToken returned in response
|
|
- name: X-CSRF-Token
|
|
in: header
|
|
schema:
|
|
type: string
|
|
description: CSRF token received from login/register response (required for web clients only)
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
refreshToken:
|
|
type: string
|
|
description: Refresh token (required for mobile/desktop/server clients only)
|
|
responses:
|
|
'200':
|
|
description: Token refreshed successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
user:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
accessToken:
|
|
type: string
|
|
csrfToken:
|
|
type: string
|
|
nullable: true
|
|
description: New CSRF token for subsequent refresh requests (web clients only)
|
|
refreshToken:
|
|
type: string
|
|
nullable: true
|
|
description: New refresh token for mobile/desktop/server clients (must be persisted for next refresh)
|
|
'401':
|
|
description: No refresh token provided or user not found
|
|
'403':
|
|
description: Invalid CSRF token
|
|
|
|
/api/auth/logout:
|
|
post:
|
|
summary: Logout user
|
|
description: Logout and clear refresh token cookie
|
|
tags:
|
|
- Client
|
|
responses:
|
|
'200':
|
|
description: Logged out successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
message:
|
|
type: string
|
|
|
|
/api/auth/sessions/current:
|
|
get:
|
|
summary: Get current session
|
|
description: |
|
|
Returns the currently authenticated user's basic info from the access token.
|
|
Project admin tokens return a projectAdmin session object instead of an auth.users row.
|
|
|
|
This endpoint does not refresh expired access tokens by itself.
|
|
For browser apps using the TypeScript SDK, call `auth.getCurrentUser()`
|
|
during startup. The SDK will use the httpOnly refresh cookie automatically
|
|
when it can refresh the session. Server, mobile, and other non-browser
|
|
clients should call `/api/auth/refresh` explicitly.
|
|
tags:
|
|
- Client
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Current session info
|
|
content:
|
|
application/json:
|
|
schema:
|
|
oneOf:
|
|
- type: object
|
|
required:
|
|
- user
|
|
additionalProperties: false
|
|
properties:
|
|
user:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
- type: object
|
|
required:
|
|
- projectAdmin
|
|
additionalProperties: false
|
|
properties:
|
|
projectAdmin:
|
|
$ref: '#/components/schemas/ProjectAdminResponse'
|
|
'401':
|
|
description: Unauthorized
|
|
|
|
/api/auth/admin/sessions:
|
|
post:
|
|
summary: Admin login
|
|
description: Authenticates admin user for dashboard access
|
|
tags:
|
|
- Admin
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- username
|
|
- password
|
|
properties:
|
|
username:
|
|
type: string
|
|
example: admin
|
|
password:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Admin login successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
projectAdmin:
|
|
$ref: '#/components/schemas/ProjectAdminResponse'
|
|
accessToken:
|
|
type: string
|
|
csrfToken:
|
|
type: string
|
|
description: CSRF token for `/api/auth/admin/refresh`
|
|
'401':
|
|
description: Invalid credentials
|
|
'403':
|
|
description: User is not an admin
|
|
|
|
/api/auth/admin/sessions/exchange:
|
|
post:
|
|
summary: Exchange cloud provider authorization code for admin session
|
|
description: Verifies an authorization code/JWT from from Insforge Cloud platform and issues an internal admin session token with project_admin role
|
|
tags:
|
|
- Admin
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- code
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: Authorization code or JWT from the Insforge
|
|
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
responses:
|
|
'200':
|
|
description: Cloud authorization verified, admin session created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
projectAdmin:
|
|
$ref: '#/components/schemas/ProjectAdminResponse'
|
|
accessToken:
|
|
type: string
|
|
description: Internal JWT for admin authentication
|
|
csrfToken:
|
|
type: string
|
|
description: CSRF token for `/api/auth/admin/refresh`
|
|
'400':
|
|
description: Invalid authorization code or JWT verification failed
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/api/auth/admin/refresh:
|
|
post:
|
|
summary: Refresh admin dashboard access token
|
|
description: Uses the dashboard-only httpOnly `insforge_admin_refresh_token` cookie with an `X-CSRF-Token` header.
|
|
tags:
|
|
- Admin
|
|
parameters:
|
|
- name: X-CSRF-Token
|
|
in: header
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: CSRF token returned from admin login or admin refresh
|
|
responses:
|
|
'200':
|
|
description: Admin token refreshed successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
projectAdmin:
|
|
$ref: '#/components/schemas/ProjectAdminResponse'
|
|
accessToken:
|
|
type: string
|
|
csrfToken:
|
|
type: string
|
|
description: CSRF token for the next admin refresh request
|
|
'401':
|
|
description: No admin refresh token provided or project admin not found
|
|
'403':
|
|
description: Invalid CSRF token
|
|
|
|
/api/auth/admin/logout:
|
|
post:
|
|
summary: Logout admin dashboard session
|
|
description: Clears the dashboard-only `insforge_admin_refresh_token` cookie.
|
|
tags:
|
|
- Admin
|
|
responses:
|
|
'200':
|
|
description: Logged out successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
message:
|
|
type: string
|
|
|
|
/api/auth/tokens/anon:
|
|
post:
|
|
summary: Get anon key (deprecated)
|
|
deprecated: true
|
|
description: >-
|
|
Deprecated - use GET /api/metadata/anon-key instead. Returns the
|
|
project's opaque anon key (`anon_...`) under the legacy `accessToken`
|
|
field for backward compatibility. The anon key is a non-secret client
|
|
identifier that maps requests to the `anon` role; it replaces the
|
|
former non-expiring anonymous JWT and can be rotated via
|
|
POST /api/secrets/anon-key/rotate (admin only).
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Anon key retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
accessToken:
|
|
type: string
|
|
description: Opaque anon key (legacy field name kept for compatibility)
|
|
example: "anon_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd"
|
|
message:
|
|
type: string
|
|
description: Success message
|
|
example: "Anon key retrieved successfully (deprecated route, use GET /api/metadata/anon-key)"
|
|
'401':
|
|
description: Unauthorized - requires authentication
|
|
'403':
|
|
description: Forbidden - admin access required
|
|
'404':
|
|
description: Anon key not initialized
|
|
|
|
/api/auth/email/send-verification:
|
|
post:
|
|
summary: Send email verification (code or link based on config)
|
|
description: Send email verification using the method configured in auth settings (verifyEmailMethod). When method is 'code', sends a 6-digit numeric code. When method is 'link', sends a browser verification link that goes through an InsForge backend endpoint first. Prevents user enumeration by returning success even if email doesn't exist.
|
|
tags:
|
|
- Client
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- email
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: user@example.com
|
|
redirectTo:
|
|
type: string
|
|
format: uri
|
|
description: >-
|
|
Used for link-based email verification. The email link always
|
|
opens an InsForge backend endpoint first; after the token is
|
|
verified, InsForge redirects the browser to this URL. This URL
|
|
must be included in allowedRedirectUrls. Recommended: use your
|
|
app's sign-in page.
|
|
responses:
|
|
'202':
|
|
description: Verification email sent (if email exists). Message varies based on configured method.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
message:
|
|
type: string
|
|
example: "If your email is registered, we have sent you a verification code/link. Please check your inbox."
|
|
'400':
|
|
description: Invalid request
|
|
|
|
/api/auth/email/verify-link:
|
|
get:
|
|
summary: Verify email from browser link click
|
|
description: |
|
|
Browser-oriented link verification flow.
|
|
|
|
This endpoint is intended for users clicking verification links in email.
|
|
It validates the token on the backend and redirects the browser to the
|
|
stored, validated `redirectTo` URL with the verification result.
|
|
|
|
Redirect query params:
|
|
- Success: `insforge_status=success&insforge_type=verify_email`
|
|
- Error: `insforge_status=error&insforge_type=verify_email&insforge_error=...`
|
|
- `insforge_status`: `success` or `error`
|
|
- `insforge_type`: always `verify_email`
|
|
- `insforge_error`: present only on error, human-readable message
|
|
|
|
Recommended handling: use your sign-in page as `redirectTo`. When the
|
|
redirect arrives with `insforge_status=success`, show a confirmation message
|
|
and ask the user to sign in with their email and password.
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: token
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: 64-character email verification token from the email link
|
|
responses:
|
|
'302':
|
|
description: Browser redirected to the stored redirect URL
|
|
'400':
|
|
description: Invalid verification token or redirect target
|
|
|
|
/api/auth/email/verify:
|
|
post:
|
|
summary: Verify email with code
|
|
description: |
|
|
Verify email address with a 6-digit code.
|
|
|
|
Successfully verified users will receive a session token.
|
|
|
|
Browser email clicks should use `GET /api/auth/email/verify-link`.
|
|
`POST /api/auth/email/verify` is the JSON API for 6-digit code submission.
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: client_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [web, mobile, desktop, server]
|
|
default: web
|
|
description: |
|
|
Client type determines how refresh tokens are returned:
|
|
- web: Refresh token stored in httpOnly cookie, csrfToken returned in response
|
|
- mobile/desktop/server: refreshToken returned directly in response body
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- email
|
|
- otp
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
description: User email address
|
|
example: user@example.com
|
|
otp:
|
|
type: string
|
|
pattern: '^\d{6}$'
|
|
description: 6-digit verification code
|
|
example: "123456"
|
|
responses:
|
|
'200':
|
|
description: Email verified successfully, session created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
user:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
accessToken:
|
|
type: string
|
|
description: JWT authentication token
|
|
csrfToken:
|
|
type: string
|
|
nullable: true
|
|
description: CSRF token for use with refresh endpoint (web clients only)
|
|
refreshToken:
|
|
type: string
|
|
nullable: true
|
|
description: Refresh token for mobile/desktop/server clients (null for web clients)
|
|
'400':
|
|
description: Invalid verification code or token
|
|
'401':
|
|
description: Verification code/token expired or invalid
|
|
|
|
/api/auth/email/send-reset-password:
|
|
post:
|
|
summary: Send password reset (code or link based on config)
|
|
description: Send password reset email using the method configured in auth settings (resetPasswordMethod). When method is 'code', sends a 6-digit numeric code for two-step flow. When method is 'link', sends a browser reset link that goes through an InsForge backend endpoint first. Prevents user enumeration by returning success even if email doesn't exist.
|
|
tags:
|
|
- Client
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- email
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: user@example.com
|
|
redirectTo:
|
|
type: string
|
|
format: uri
|
|
description: >-
|
|
Used for link-based password reset. The email link always
|
|
opens an InsForge backend endpoint first; InsForge then
|
|
redirects the browser to this URL with the reset token in
|
|
the query string. This URL must be included in
|
|
allowedRedirectUrls. Recommended: use your app's dedicated
|
|
reset-password page.
|
|
responses:
|
|
'202':
|
|
description: Password reset email sent (if email exists). Message varies based on configured method.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
message:
|
|
type: string
|
|
example: "If your email is registered, we have sent you a password reset code/link. Please check your inbox."
|
|
'400':
|
|
description: Invalid request
|
|
|
|
/api/auth/email/exchange-reset-password-token:
|
|
post:
|
|
summary: Exchange reset password code for reset token
|
|
description: |
|
|
Step 1 of two-step password reset flow (only used when resetPasswordMethod is 'code'):
|
|
1. Verify the 6-digit code sent to user's email
|
|
2. Return a reset token that can be used to actually reset the password
|
|
|
|
This endpoint is not used when resetPasswordMethod is 'link', because the browser reset-link flow uses the emailed link token directly.
|
|
tags:
|
|
- Client
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- email
|
|
- code
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: user@example.com
|
|
code:
|
|
type: string
|
|
pattern: '^\d{6}$'
|
|
description: 6-digit numeric code from email
|
|
example: "123456"
|
|
responses:
|
|
'200':
|
|
description: Code verified successfully, reset token returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
token:
|
|
type: string
|
|
description: Reset token to be used in reset-password endpoint
|
|
expiresAt:
|
|
type: string
|
|
format: date-time
|
|
description: Token expiration timestamp
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Invalid or expired code
|
|
|
|
/api/auth/email/reset-password-link:
|
|
get:
|
|
summary: Open password reset flow from browser link click
|
|
description: |
|
|
Browser-oriented password reset link flow.
|
|
|
|
This endpoint is intended for users clicking password reset links in email.
|
|
It validates the token on the backend and redirects the browser to the
|
|
stored, validated `redirectTo` URL with the reset token in the query string.
|
|
|
|
Redirect query params:
|
|
- Ready: `token=...&insforge_status=ready&insforge_type=reset_password`
|
|
- Error: `insforge_status=error&insforge_type=reset_password&insforge_error=...`
|
|
- `token`: present only when `insforge_status=ready`
|
|
- `insforge_status`: `ready` or `error`
|
|
- `insforge_type`: always `reset_password`
|
|
- `insforge_error`: present only on error, human-readable message
|
|
|
|
Your app should render the reset-password form only when `insforge_status=ready`
|
|
and `token` is present.
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: token
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: 64-character password reset token from the email link
|
|
responses:
|
|
'302':
|
|
description: Browser redirected to the stored redirect URL
|
|
'400':
|
|
description: Invalid reset token or redirect target
|
|
|
|
/api/auth/email/reset-password:
|
|
post:
|
|
summary: Reset password with token
|
|
description: |
|
|
Reset user password with a token. The token can be:
|
|
- Magic link token (64-character hex token from send-reset-password when method is 'link')
|
|
- Reset token (from exchange-reset-password-token after code verification when method is 'code')
|
|
|
|
Both token types use RESET_PASSWORD purpose and are verified the same way.
|
|
|
|
Flow summary:
|
|
- Code method: send-reset-password → exchange-reset-password-token → reset-password (with resetToken)
|
|
- Link method: send-reset-password → GET /api/auth/email/reset-password-link → reset-password
|
|
tags:
|
|
- Client
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- newPassword
|
|
- otp
|
|
properties:
|
|
newPassword:
|
|
type: string
|
|
description: New password meeting configured requirements
|
|
example: newSecurePassword123
|
|
otp:
|
|
type: string
|
|
description: Reset token (either from magic link or from exchange-reset-password-token endpoint)
|
|
example: "a1b2c3d4..."
|
|
responses:
|
|
'200':
|
|
description: Password reset successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "Password reset successfully"
|
|
'400':
|
|
description: Invalid request or password requirements not met
|
|
'401':
|
|
description: Verification code/token expired or invalid
|
|
|
|
/api/auth/oauth/configs:
|
|
get:
|
|
summary: List all OAuth configurations
|
|
description: Get all configured OAuth providers (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of OAuth configurations
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/OAuthConfig'
|
|
count:
|
|
type: integer
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
post:
|
|
summary: Create OAuth configuration
|
|
description: Create a new OAuth provider configuration (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- provider
|
|
properties:
|
|
provider:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
clientId:
|
|
type: string
|
|
clientSecret:
|
|
type: string
|
|
redirectUri:
|
|
type: string
|
|
scopes:
|
|
type: array
|
|
items:
|
|
type: string
|
|
useSharedKey:
|
|
type: boolean
|
|
responses:
|
|
'200':
|
|
description: OAuth configuration created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OAuthConfig'
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
/api/auth/oauth/{provider}/config:
|
|
get:
|
|
summary: Get OAuth configuration for specific provider
|
|
description: Get OAuth configuration including client secret (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: provider
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
responses:
|
|
'200':
|
|
description: OAuth configuration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: '#/components/schemas/OAuthConfig'
|
|
- type: object
|
|
properties:
|
|
clientSecret:
|
|
type: string
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: Configuration not found
|
|
|
|
put:
|
|
summary: Update OAuth configuration
|
|
description: Update OAuth provider configuration (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: provider
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
clientId:
|
|
type: string
|
|
clientSecret:
|
|
type: string
|
|
redirectUri:
|
|
type: string
|
|
scopes:
|
|
type: array
|
|
items:
|
|
type: string
|
|
useSharedKey:
|
|
type: boolean
|
|
responses:
|
|
'200':
|
|
description: Configuration updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OAuthConfig'
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: Configuration not found
|
|
|
|
delete:
|
|
summary: Delete OAuth configuration
|
|
description: Delete OAuth provider configuration (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: provider
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
responses:
|
|
'200':
|
|
description: Configuration deleted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
message:
|
|
type: string
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: Configuration not found
|
|
|
|
/api/auth/oauth/{provider}:
|
|
get:
|
|
summary: Initiate OAuth flow (PKCE)
|
|
description: |
|
|
Generate OAuth authorization URL for any supported provider using PKCE flow.
|
|
|
|
For mobile/desktop/server clients using PKCE:
|
|
1. Generate code_verifier (random string, 43-128 chars)
|
|
2. Generate code_challenge = Base64URL(SHA256(code_verifier))
|
|
3. Call this endpoint with code_challenge
|
|
4. After OAuth callback, use /api/auth/oauth/exchange with code_verifier
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: provider
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
- name: redirect_uri
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
description: URL to redirect after authentication (receives insforge_code parameter)
|
|
- name: code_challenge
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
description: |
|
|
PKCE code challenge for mobile/desktop/server clients.
|
|
Generate using: Base64URL(SHA256(code_verifier))
|
|
Required for secure token exchange in native apps or trusted server-side clients.
|
|
responses:
|
|
'200':
|
|
description: OAuth authorization URL
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
authUrl:
|
|
type: string
|
|
format: uri
|
|
description: URL to redirect user for OAuth provider login
|
|
'400':
|
|
description: Invalid request or provider not supported
|
|
'500':
|
|
description: OAuth not configured
|
|
|
|
/api/auth/oauth/exchange:
|
|
post:
|
|
summary: Exchange OAuth code for tokens (PKCE)
|
|
description: |
|
|
Exchange the insforge_code (received from OAuth callback) for access and refresh tokens.
|
|
|
|
This endpoint is used for PKCE flow in mobile/desktop/server clients:
|
|
1. After OAuth callback, your redirect_uri receives `insforge_code` parameter
|
|
2. Call this endpoint with the code and your original code_verifier
|
|
3. Receive access token and refresh token in response
|
|
|
|
The code_verifier must match the code_challenge sent during OAuth initiation.
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: client_type
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [web, mobile, desktop, server]
|
|
default: web
|
|
description: |
|
|
Client type determines how refresh tokens are returned:
|
|
- web: Refresh token stored in httpOnly cookie, csrfToken returned in response
|
|
- mobile/desktop/server: refreshToken returned directly in response body
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- code
|
|
- code_verifier
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: The insforge_code received from OAuth callback redirect
|
|
example: "abc123..."
|
|
code_verifier:
|
|
type: string
|
|
description: |
|
|
The original code_verifier used to generate code_challenge.
|
|
Must be 43-128 characters, using [A-Za-z0-9-._~]
|
|
example: "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
|
responses:
|
|
'200':
|
|
description: Tokens exchanged successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
user:
|
|
$ref: '#/components/schemas/UserResponse'
|
|
accessToken:
|
|
type: string
|
|
description: JWT access token for API authentication
|
|
refreshToken:
|
|
type: string
|
|
description: Refresh token for obtaining new access tokens
|
|
'400':
|
|
description: Invalid request - missing code or code_verifier
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'401':
|
|
description: Invalid or expired code, or code_verifier mismatch
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/api/auth/oauth/shared/callback/{state}:
|
|
get:
|
|
summary: Shared OAuth callback handler
|
|
description: Handles OAuth callbacks from InsForge Cloud shared OAuth
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: state
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: JWT state parameter
|
|
- name: success
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Success flag
|
|
- name: error
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Error message
|
|
- name: payload
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Base64 encoded user payload
|
|
responses:
|
|
'302':
|
|
description: Redirect to application with access token or error
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
|
|
/api/auth/oauth/{provider}/callback:
|
|
get:
|
|
summary: Provider-specific OAuth callback (GET)
|
|
description: |
|
|
OAuth callback endpoint for provider-specific flows (most providers use GET).
|
|
|
|
Response varies based on the original OAuth initiation:
|
|
- With code_challenge (PKCE): Redirects with `insforge_code` for exchange endpoint
|
|
- Without code_challenge (web): Redirects with `access_token` and sets httpOnly cookie
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: provider
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
- name: code
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Authorization code from OAuth provider
|
|
- name: state
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: JWT state with redirect URI and optional code_challenge
|
|
- name: token
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Direct ID token (for some providers)
|
|
responses:
|
|
'302':
|
|
description: |
|
|
Redirect to application.
|
|
- PKCE flow: redirect_uri?insforge_code={code}&user_id={id}&email={email}&name={name}
|
|
- Web flow: redirect_uri?access_token={token}&user_id={id}&email={email}&name={name}&csrf_token={csrf}
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
description: Redirect URL with authentication parameters
|
|
|
|
post:
|
|
summary: Provider-specific OAuth callback (POST)
|
|
description: |
|
|
OAuth callback endpoint for providers that use POST (e.g., Apple with form_post response mode).
|
|
|
|
Response varies based on the original OAuth initiation:
|
|
- With code_challenge (PKCE): Redirects with `insforge_code` for exchange endpoint
|
|
- Without code_challenge (web): Redirects with `access_token` and sets httpOnly cookie
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: provider
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- state
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: Authorization code from OAuth provider
|
|
state:
|
|
type: string
|
|
description: JWT state with redirect URI and optional code_challenge
|
|
id_token:
|
|
type: string
|
|
description: ID token (for Apple Sign In)
|
|
responses:
|
|
'302':
|
|
description: |
|
|
Redirect to application.
|
|
- PKCE flow: redirect_uri?insforge_code={code}&user_id={id}&email={email}&name={name}
|
|
- Web flow: redirect_uri?access_token={token}&user_id={id}&email={email}&name={name}&csrf_token={csrf}
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
description: Redirect URL with authentication parameters
|
|
|
|
/api/auth/oauth/custom/configs:
|
|
get:
|
|
summary: List all custom OAuth configurations
|
|
description: Get all configured custom OAuth providers (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of custom OAuth configurations
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CustomOAuthConfig'
|
|
count:
|
|
type: integer
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
|
|
post:
|
|
summary: Create custom OAuth configuration
|
|
description: Create a new custom OAuth provider configuration (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- key
|
|
- name
|
|
- discoveryEndpoint
|
|
- clientId
|
|
- clientSecret
|
|
properties:
|
|
key:
|
|
type: string
|
|
name:
|
|
type: string
|
|
discoveryEndpoint:
|
|
type: string
|
|
format: uri
|
|
clientId:
|
|
type: string
|
|
clientSecret:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Custom OAuth configuration created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CustomOAuthConfig'
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'409':
|
|
description: Configuration already exists
|
|
|
|
/api/auth/oauth/custom/{key}/config:
|
|
get:
|
|
summary: Get custom OAuth configuration
|
|
description: Get a custom OAuth configuration including client secret (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: key
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Custom OAuth configuration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: '#/components/schemas/CustomOAuthConfig'
|
|
- type: object
|
|
properties:
|
|
clientSecret:
|
|
type: string
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: Configuration not found
|
|
|
|
put:
|
|
summary: Update custom OAuth configuration
|
|
description: Update a custom OAuth provider configuration (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: key
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
discoveryEndpoint:
|
|
type: string
|
|
format: uri
|
|
clientId:
|
|
type: string
|
|
clientSecret:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Custom OAuth configuration updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CustomOAuthConfig'
|
|
'400':
|
|
description: Invalid request
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: Configuration not found
|
|
|
|
delete:
|
|
summary: Delete custom OAuth configuration
|
|
description: Delete a custom OAuth provider configuration (admin only)
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: key
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Configuration deleted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
message:
|
|
type: string
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden - Admin only
|
|
'404':
|
|
description: Configuration not found
|
|
|
|
/api/auth/oauth/custom/{key}:
|
|
get:
|
|
summary: Initiate custom OAuth flow (PKCE)
|
|
description: Generate OAuth authorization URL for a configured custom OAuth provider using PKCE flow
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: key
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: redirect_uri
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
description: URL to redirect after authentication (receives insforge_code parameter)
|
|
- name: code_challenge
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
description: PKCE code challenge for mobile/desktop/server clients
|
|
responses:
|
|
'200':
|
|
description: OAuth authorization URL
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
authUrl:
|
|
type: string
|
|
format: uri
|
|
'400':
|
|
description: Invalid request
|
|
'404':
|
|
description: Custom OAuth provider not found
|
|
|
|
/api/auth/oauth/custom/{key}/callback:
|
|
get:
|
|
summary: Custom OAuth callback (GET)
|
|
description: OAuth callback endpoint for custom OAuth providers
|
|
tags:
|
|
- Client
|
|
parameters:
|
|
- name: key
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: code
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Authorization code from the custom OAuth provider
|
|
- name: state
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Signed OAuth state payload
|
|
responses:
|
|
'302':
|
|
description: Redirect to application after custom OAuth completion
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
description: Redirect URL with authentication parameters
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
apiKey:
|
|
type: apiKey
|
|
in: header
|
|
name: x-api-key
|
|
|
|
schemas:
|
|
ProjectAdminResponse:
|
|
type: object
|
|
required:
|
|
- subject
|
|
- username
|
|
properties:
|
|
subject:
|
|
type: string
|
|
example: local:admin
|
|
username:
|
|
type: string
|
|
example: admin
|
|
|
|
UserResponse:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
email:
|
|
type: string
|
|
format: email
|
|
profile:
|
|
type: object
|
|
nullable: true
|
|
additionalProperties: true
|
|
description: User profile data (name, avatar_url, and custom fields)
|
|
properties:
|
|
name:
|
|
type: string
|
|
avatar_url:
|
|
type: string
|
|
format: uri
|
|
metadata:
|
|
type: object
|
|
nullable: true
|
|
additionalProperties: true
|
|
description: System metadata (device ID, login IP, etc.)
|
|
emailVerified:
|
|
type: boolean
|
|
providers:
|
|
type: array
|
|
items:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
ProfileResponse:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
description: User ID
|
|
profile:
|
|
type: object
|
|
nullable: true
|
|
additionalProperties: true
|
|
description: User profile data (can contain custom fields)
|
|
properties:
|
|
name:
|
|
type: string
|
|
avatar_url:
|
|
type: string
|
|
format: uri
|
|
|
|
OAuthConfig:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
provider:
|
|
type: string
|
|
enum: [google, github, discord, linkedin, facebook, instagram, tiktok, apple, x, spotify, microsoft]
|
|
clientId:
|
|
type: string
|
|
nullable: true
|
|
redirectUri:
|
|
type: string
|
|
nullable: true
|
|
scopes:
|
|
type: array
|
|
items:
|
|
type: string
|
|
nullable: true
|
|
useSharedKey:
|
|
type: boolean
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
CustomOAuthConfig:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
key:
|
|
type: string
|
|
name:
|
|
type: string
|
|
discoveryEndpoint:
|
|
type: string
|
|
format: uri
|
|
clientId:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
AuthRecord:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
email:
|
|
type: string
|
|
format: email
|
|
passwordHash:
|
|
type: string
|
|
description: SHA256 hash of password
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
ProfileRecord:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
authId:
|
|
type: string
|
|
format: uuid
|
|
description: Foreign key to auth table
|
|
name:
|
|
type: string
|
|
avatar_url:
|
|
type: string
|
|
nullable: true
|
|
bio:
|
|
type: string
|
|
nullable: true
|
|
metadata:
|
|
type: object
|
|
description: JSONB field for flexible data
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
required:
|
|
- error
|
|
- message
|
|
- statusCode
|
|
properties:
|
|
error:
|
|
type: string
|
|
description: Error code for programmatic handling
|
|
example: "VALIDATION_ERROR"
|
|
message:
|
|
type: string
|
|
description: Human-readable error message
|
|
example: "Email is already in use"
|
|
statusCode:
|
|
type: integer
|
|
description: HTTP status code
|
|
example: 400
|
|
nextActions:
|
|
type: string
|
|
description: Suggested action to resolve the error
|
|
example: "Please use a different email address"
|