@55387.ai/uniauth-client 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/ai-prompts/full-stack.md +167 -0
- package/ai-prompts/mobile-trusted-client.md +185 -0
- package/ai-prompts/oauth2-provider.md +176 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -69,6 +69,9 @@ auth.startSocialLogin('google');
|
|
|
69
69
|
### 🔐 SSO / 单点登录
|
|
70
70
|
|
|
71
71
|
```typescript
|
|
72
|
+
// ⚠️ Must call configureSso() before using loginWithSSO()
|
|
73
|
+
// ⚠️ 使用 loginWithSSO() 前必须调用 configureSso()
|
|
74
|
+
|
|
72
75
|
// Configure / 配置
|
|
73
76
|
auth.configureSso({
|
|
74
77
|
ssoUrl: 'https://sso.55387.xyz',
|
|
@@ -164,6 +167,31 @@ try {
|
|
|
164
167
|
}
|
|
165
168
|
```
|
|
166
169
|
|
|
170
|
+
## 🤖 AI Agent Prompts / AI 智能体提示词
|
|
171
|
+
|
|
172
|
+
This package includes AI-ready integration prompts for multiple scenarios. Copy them into your AI coding assistant (Claude, Cursor, Copilot, etc.) to generate a complete UniAuth integration automatically.
|
|
173
|
+
|
|
174
|
+
本包附带多个场景的 AI 集成提示词。将其复制到 AI 编程助手中,即可自动生成完整的 UniAuth 集成代码。
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# After install, find prompts at:
|
|
178
|
+
# 安装后,提示词文件位于:
|
|
179
|
+
ls node_modules/@55387.ai/uniauth-client/ai-prompts/
|
|
180
|
+
# → full-stack.md, oauth2-provider.md, mobile-trusted-client.md
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| Prompt | Scenario / 场景 |
|
|
184
|
+
|--------|----------------|
|
|
185
|
+
| `full-stack.md` | Full-stack app with React + Node.js / 全栈应用 |
|
|
186
|
+
| `oauth2-provider.md` | Use UniAuth as OAuth2/OIDC provider / OAuth2 提供者 |
|
|
187
|
+
| `mobile-trusted-client.md` | Mobile & trusted client API / 移动端可信客户端 |
|
|
188
|
+
|
|
189
|
+
> [!TIP]
|
|
190
|
+
> Replace placeholders like `YOUR_UNIAUTH_URL` and `YOUR_CLIENT_ID` before pasting into your AI assistant.
|
|
191
|
+
> 粘贴到 AI 助手前,请替换 `YOUR_UNIAUTH_URL` 和 `YOUR_CLIENT_ID` 等占位符。
|
|
192
|
+
|
|
193
|
+
See all prompts: [docs/ai-prompts/](../../docs/ai-prompts/README.md)
|
|
194
|
+
|
|
167
195
|
## License
|
|
168
196
|
|
|
169
197
|
MIT
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# 🤖 AI Prompt: Full-Stack App with UniAuth
|
|
2
|
+
|
|
3
|
+
> Copy everything below the line and paste into your AI coding assistant.
|
|
4
|
+
>
|
|
5
|
+
> 复制下方分割线以下的全部内容,粘贴到你的 AI 编程助手中。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are an expert full-stack TypeScript developer. Help me build a complete web application with UniAuth authentication, from scratch.
|
|
10
|
+
|
|
11
|
+
## Project Context
|
|
12
|
+
|
|
13
|
+
- **UniAuth Server URL**: `YOUR_UNIAUTH_URL` (e.g. `https://auth.55387.xyz`)
|
|
14
|
+
- **Client ID**: `YOUR_CLIENT_ID`
|
|
15
|
+
- **Client Secret**: `YOUR_CLIENT_SECRET` (backend only!)
|
|
16
|
+
- **App Key**: `YOUR_APP_KEY`
|
|
17
|
+
- **Redirect URI**: `YOUR_REDIRECT_URI` (e.g. `http://localhost:5173/auth/callback`)
|
|
18
|
+
|
|
19
|
+
## SDK Packages
|
|
20
|
+
|
|
21
|
+
### Frontend: `@55387.ai/uniauth-react`
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @55387.ai/uniauth-react
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**UniAuthProvider** — Wrap your app:
|
|
28
|
+
```tsx
|
|
29
|
+
import { UniAuthProvider } from '@55387.ai/uniauth-react';
|
|
30
|
+
|
|
31
|
+
<UniAuthProvider config={{
|
|
32
|
+
baseUrl: 'YOUR_UNIAUTH_URL',
|
|
33
|
+
appKey: 'YOUR_APP_KEY',
|
|
34
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
35
|
+
storage: 'localStorage',
|
|
36
|
+
sso: {
|
|
37
|
+
ssoUrl: 'YOUR_UNIAUTH_URL',
|
|
38
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
39
|
+
redirectUri: 'YOUR_REDIRECT_URI',
|
|
40
|
+
scope: 'openid profile email',
|
|
41
|
+
},
|
|
42
|
+
}}>
|
|
43
|
+
<App />
|
|
44
|
+
</UniAuthProvider>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**useUniAuth()** — Access auth state:
|
|
48
|
+
```tsx
|
|
49
|
+
const { user, isAuthenticated, isLoading, login, logout, updateProfile, client, getToken } = useUniAuth();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Key client methods** (via `client`):
|
|
53
|
+
```typescript
|
|
54
|
+
await client.sendCode(phone, 'login'); // SMS code
|
|
55
|
+
await client.loginWithCode(phone, code); // Phone login
|
|
56
|
+
await client.sendEmailCode(email, 'login'); // Email code
|
|
57
|
+
await client.loginWithEmailCode(email, code); // Email code login
|
|
58
|
+
await client.loginWithEmail(email, password); // Email password login
|
|
59
|
+
await client.registerWithEmail(email, password, nickname);
|
|
60
|
+
await client.verifyMFA(mfaToken, code); // MFA step
|
|
61
|
+
client.startSocialLogin('google'); // Social login redirect
|
|
62
|
+
client.loginWithSSO({ usePKCE: true }); // SSO redirect
|
|
63
|
+
await client.getAccessToken(); // Auto-refresh token
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Types**:
|
|
67
|
+
```typescript
|
|
68
|
+
interface UserInfo { id: string; phone: string|null; email: string|null; nickname: string|null; avatar_url: string|null; }
|
|
69
|
+
interface LoginResult { user: UserInfo; access_token: string; refresh_token: string; expires_in: number; is_new_user: boolean; mfa_required?: boolean; mfa_token?: string; }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Backend: `@55387.ai/uniauth-server`
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install @55387.ai/uniauth-server
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { UniAuthServer, ServerAuthError } from '@55387.ai/uniauth-server';
|
|
80
|
+
|
|
81
|
+
const auth = new UniAuthServer({
|
|
82
|
+
baseUrl: process.env.UNIAUTH_URL!,
|
|
83
|
+
clientId: process.env.UNIAUTH_CLIENT_ID!,
|
|
84
|
+
clientSecret: process.env.UNIAUTH_CLIENT_SECRET!,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Express middleware
|
|
88
|
+
app.use('/api/*', auth.middleware());
|
|
89
|
+
// req.user → UserInfo, req.authPayload → TokenPayload
|
|
90
|
+
|
|
91
|
+
// Hono middleware
|
|
92
|
+
app.use('/api/*', auth.honoMiddleware());
|
|
93
|
+
// c.get('user') → UserInfo, c.get('authPayload') → TokenPayload
|
|
94
|
+
|
|
95
|
+
// Manual verification
|
|
96
|
+
const payload = await auth.verifyToken(token);
|
|
97
|
+
const user = await auth.getUser(payload.sub);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Requirements
|
|
101
|
+
|
|
102
|
+
### Architecture
|
|
103
|
+
- **Frontend**: React + Vite (or Next.js)
|
|
104
|
+
- **Backend**: Express or Hono
|
|
105
|
+
- **Language**: TypeScript throughout
|
|
106
|
+
- **Auth**: Frontend sends `Authorization: Bearer <token>` header, backend validates via `@55387.ai/uniauth-server`
|
|
107
|
+
|
|
108
|
+
### Frontend Features
|
|
109
|
+
1. **Login Page**: SSO login button + optional phone/email login tabs
|
|
110
|
+
2. **Protected Routes**: Redirect to login if not authenticated
|
|
111
|
+
3. **Dashboard**: Show user info, sample data from protected API
|
|
112
|
+
4. **Settings Page** (required):
|
|
113
|
+
- Language: Chinese 中文 / English
|
|
114
|
+
- Theme: Dark / Light / System
|
|
115
|
+
- User profile display (nickname, avatar, email)
|
|
116
|
+
- Logout button
|
|
117
|
+
5. **Toast Notifications**: Never use `alert()` or `confirm()`
|
|
118
|
+
6. **i18n**: Chinese + English bilingual UI
|
|
119
|
+
7. **Dark Mode**: Light, Dark, System
|
|
120
|
+
8. **Responsive**: Desktop + Tablet + Mobile
|
|
121
|
+
|
|
122
|
+
### Backend Features
|
|
123
|
+
1. **Protected API routes** using UniAuth middleware
|
|
124
|
+
2. **Public routes** for health check
|
|
125
|
+
3. **User-specific data**: Use `req.user.id` or `c.get('user').id` to scope data
|
|
126
|
+
4. **Error handling**: JSON error responses with proper status codes
|
|
127
|
+
5. **CORS**: Allow frontend origin
|
|
128
|
+
|
|
129
|
+
### Design Tokens (Fan Design System)
|
|
130
|
+
```
|
|
131
|
+
Primary: #07C160 | Error: #FA5151 | Warning: #FFBE00 | Link: #576B95
|
|
132
|
+
Border Radius: button 8px, card 12px, input 4px
|
|
133
|
+
Font: base 17px, h1 20px, caption 14px, small 12px
|
|
134
|
+
Spacing: page edge 16px, element gap 8px, unit 4px
|
|
135
|
+
Background Light: page #F2F2F2, card #FFFFFF
|
|
136
|
+
Background Dark: page #111111, card #191919
|
|
137
|
+
Text Light: primary rgba(0,0,0,0.9), secondary rgba(0,0,0,0.5)
|
|
138
|
+
Text Dark: primary rgba(255,255,255,0.8), secondary rgba(255,255,255,0.5)
|
|
139
|
+
Button height: 48px, Navbar height: 44px
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Environment Variables
|
|
143
|
+
|
|
144
|
+
**Frontend** (`.env`):
|
|
145
|
+
```env
|
|
146
|
+
VITE_UNIAUTH_URL=YOUR_UNIAUTH_URL
|
|
147
|
+
VITE_UNIAUTH_CLIENT_ID=YOUR_CLIENT_ID
|
|
148
|
+
VITE_UNIAUTH_APP_KEY=YOUR_APP_KEY
|
|
149
|
+
VITE_UNIAUTH_REDIRECT_URI=http://localhost:5173/auth/callback
|
|
150
|
+
VITE_API_URL=http://localhost:3000
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Backend** (`.env`):
|
|
154
|
+
```env
|
|
155
|
+
UNIAUTH_URL=YOUR_UNIAUTH_URL
|
|
156
|
+
UNIAUTH_CLIENT_ID=YOUR_CLIENT_ID
|
|
157
|
+
UNIAUTH_CLIENT_SECRET=YOUR_CLIENT_SECRET
|
|
158
|
+
PORT=3000
|
|
159
|
+
FRONTEND_URL=http://localhost:5173
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Testing
|
|
163
|
+
- Frontend: Vitest + React Testing Library
|
|
164
|
+
- Backend: Vitest + supertest
|
|
165
|
+
- Include tests for auth flow, protected routes, and error handling
|
|
166
|
+
|
|
167
|
+
Generate the complete project with both frontend and backend. Ensure all code compiles and follows TypeScript best practices.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# 🤖 AI Prompt: Mobile / Trusted Client Integration
|
|
2
|
+
|
|
3
|
+
> Copy everything below the line and paste into your AI coding assistant.
|
|
4
|
+
>
|
|
5
|
+
> 复制下方分割线以下的全部内容,粘贴到你的 AI 编程助手中。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are an expert mobile/native app developer. Help me integrate UniAuth authentication into my mobile or native application using the **Trusted Client API**.
|
|
10
|
+
|
|
11
|
+
The Trusted Client API allows server-to-server or privileged native apps to perform direct authentication (phone/email login) without browser redirects. This is ideal for mobile apps, desktop apps, and backend services.
|
|
12
|
+
|
|
13
|
+
## Project Context
|
|
14
|
+
|
|
15
|
+
- **UniAuth Server URL**: `YOUR_UNIAUTH_URL` (e.g. `https://auth.55387.xyz`)
|
|
16
|
+
- **Trusted Client ID**: `YOUR_CLIENT_ID`
|
|
17
|
+
- **Trusted Client Secret**: `YOUR_CLIENT_SECRET`
|
|
18
|
+
|
|
19
|
+
## Trusted Client API Reference
|
|
20
|
+
|
|
21
|
+
All Trusted Client endpoints require these headers:
|
|
22
|
+
|
|
23
|
+
```http
|
|
24
|
+
X-Client-Id: YOUR_CLIENT_ID
|
|
25
|
+
X-Client-Secret: YOUR_CLIENT_SECRET
|
|
26
|
+
Content-Type: application/json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Phone Authentication
|
|
30
|
+
|
|
31
|
+
**Send SMS Code:**
|
|
32
|
+
```http
|
|
33
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/phone/send-code
|
|
34
|
+
|
|
35
|
+
{
|
|
36
|
+
"phone": "+8613800138000",
|
|
37
|
+
"type": "login"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
Response: `{ "success": true, "data": { "expires_in": 300, "retry_after": 60 } }`
|
|
41
|
+
|
|
42
|
+
**Verify Phone Code:**
|
|
43
|
+
```http
|
|
44
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/phone/verify
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
"phone": "+8613800138000",
|
|
48
|
+
"code": "123456"
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
Response: `{ "success": true, "data": { "user": {...}, "access_token": "...", "refresh_token": "...", "expires_in": 3600 } }`
|
|
52
|
+
|
|
53
|
+
### Email Authentication
|
|
54
|
+
|
|
55
|
+
**Send Email Code:**
|
|
56
|
+
```http
|
|
57
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/email/send-code
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
"email": "user@example.com",
|
|
61
|
+
"type": "login"
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Verify Email Code:**
|
|
66
|
+
```http
|
|
67
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/email/verify
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
"email": "user@example.com",
|
|
71
|
+
"code": "123456"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Email Password Login:**
|
|
76
|
+
```http
|
|
77
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/email/login
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
"email": "user@example.com",
|
|
81
|
+
"password": "user_password"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### MFA Verification
|
|
86
|
+
|
|
87
|
+
When a login returns `mfa_required: true`, complete MFA:
|
|
88
|
+
```http
|
|
89
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/mfa/verify
|
|
90
|
+
|
|
91
|
+
Headers: X-Client-Id, X-Client-Secret
|
|
92
|
+
{
|
|
93
|
+
"mfa_token": "temporary_mfa_token",
|
|
94
|
+
"code": "123456"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Token Refresh
|
|
99
|
+
|
|
100
|
+
```http
|
|
101
|
+
POST YOUR_UNIAUTH_URL/api/v1/trusted/token/refresh
|
|
102
|
+
|
|
103
|
+
Headers: X-Client-Id, X-Client-Secret
|
|
104
|
+
{
|
|
105
|
+
"refresh_token": "current_refresh_token"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
Response: `{ "success": true, "data": { "access_token": "new_token", "refresh_token": "new_refresh", "expires_in": 3600 } }`
|
|
109
|
+
|
|
110
|
+
### Get User Info (with token)
|
|
111
|
+
|
|
112
|
+
```http
|
|
113
|
+
GET YOUR_UNIAUTH_URL/api/v1/user/me
|
|
114
|
+
Authorization: Bearer ACCESS_TOKEN
|
|
115
|
+
```
|
|
116
|
+
Response: `{ "success": true, "data": { "id": "...", "phone": "...", "email": "...", "nickname": "...", "avatar_url": "..." } }`
|
|
117
|
+
|
|
118
|
+
## Response Types
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Successful login response
|
|
122
|
+
interface LoginResponse {
|
|
123
|
+
success: true;
|
|
124
|
+
data: {
|
|
125
|
+
user: {
|
|
126
|
+
id: string;
|
|
127
|
+
phone: string | null;
|
|
128
|
+
email: string | null;
|
|
129
|
+
nickname: string | null;
|
|
130
|
+
avatar_url: string | null;
|
|
131
|
+
};
|
|
132
|
+
access_token: string;
|
|
133
|
+
refresh_token: string;
|
|
134
|
+
expires_in: number;
|
|
135
|
+
is_new_user: boolean;
|
|
136
|
+
mfa_required?: boolean;
|
|
137
|
+
mfa_token?: string;
|
|
138
|
+
mfa_methods?: string[];
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Error response
|
|
143
|
+
interface ErrorResponse {
|
|
144
|
+
success: false;
|
|
145
|
+
error: {
|
|
146
|
+
code: string; // e.g. 'INVALID_CODE', 'RATE_LIMITED'
|
|
147
|
+
message: string; // Human-readable error
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Requirements
|
|
153
|
+
|
|
154
|
+
1. **Auth Service Layer**: Create a service/manager class that encapsulates all Trusted Client API calls. Securely store `Client-Id` and `Client-Secret` in the app (use secure storage on mobile).
|
|
155
|
+
|
|
156
|
+
2. **Login Flow**:
|
|
157
|
+
- Phone login: Send code → Verify code → Get tokens
|
|
158
|
+
- Email login: Send code → Verify code, OR email + password login
|
|
159
|
+
- Handle `mfa_required` response → prompt user for MFA code → verify
|
|
160
|
+
|
|
161
|
+
3. **Token Management**:
|
|
162
|
+
- Store `access_token` and `refresh_token` in secure storage (Keychain on iOS, EncryptedSharedPreferences on Android)
|
|
163
|
+
- Auto-refresh tokens before expiry using the refresh endpoint
|
|
164
|
+
- Include `Authorization: Bearer <access_token>` in all API requests
|
|
165
|
+
|
|
166
|
+
4. **Error Handling**: Handle network errors, expired tokens, rate limiting, and invalid credentials gracefully. Display user-friendly error messages.
|
|
167
|
+
|
|
168
|
+
5. **UI/UX**:
|
|
169
|
+
- Login screen with phone/email tabs
|
|
170
|
+
- SMS/email code input with countdown timer
|
|
171
|
+
- MFA code input when required
|
|
172
|
+
- Loading states during API calls
|
|
173
|
+
- Toast notifications for errors (no `alert()`)
|
|
174
|
+
|
|
175
|
+
6. **Security**:
|
|
176
|
+
- Never log tokens or secrets
|
|
177
|
+
- Use HTTPS for all API calls
|
|
178
|
+
- Validate phone number format (E.164) before sending
|
|
179
|
+
- Implement retry-after logic to respect rate limits
|
|
180
|
+
|
|
181
|
+
7. **i18n**: Support Chinese and English.
|
|
182
|
+
|
|
183
|
+
8. **Testing**: Include unit tests for the auth service layer.
|
|
184
|
+
|
|
185
|
+
Generate the complete implementation for my target platform (React Native / Flutter / Swift / Kotlin).
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# 🤖 AI Prompt: OAuth2 / OIDC Provider Integration
|
|
2
|
+
|
|
3
|
+
> Copy everything below the line and paste into your AI coding assistant.
|
|
4
|
+
>
|
|
5
|
+
> 复制下方分割线以下的全部内容,粘贴到你的 AI 编程助手中。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are an expert developer specializing in OAuth2 and OpenID Connect. Help me integrate UniAuth as my application's OAuth2/OIDC provider.
|
|
10
|
+
|
|
11
|
+
## Project Context
|
|
12
|
+
|
|
13
|
+
- **UniAuth Server URL**: `YOUR_UNIAUTH_URL` (e.g. `https://auth.55387.xyz`)
|
|
14
|
+
- **Client ID**: `YOUR_CLIENT_ID`
|
|
15
|
+
- **Client Secret**: `YOUR_CLIENT_SECRET`
|
|
16
|
+
- **Redirect URI**: `YOUR_REDIRECT_URI`
|
|
17
|
+
|
|
18
|
+
## OIDC Discovery
|
|
19
|
+
|
|
20
|
+
UniAuth supports OpenID Connect Discovery. Your app can auto-configure by fetching:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
GET YOUR_UNIAUTH_URL/.well-known/openid-configuration
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Response includes:
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"issuer": "YOUR_UNIAUTH_URL",
|
|
30
|
+
"authorization_endpoint": "YOUR_UNIAUTH_URL/api/v1/oauth2/authorize",
|
|
31
|
+
"token_endpoint": "YOUR_UNIAUTH_URL/api/v1/oauth2/token",
|
|
32
|
+
"userinfo_endpoint": "YOUR_UNIAUTH_URL/api/v1/oidc/userinfo",
|
|
33
|
+
"jwks_uri": "YOUR_UNIAUTH_URL/.well-known/jwks.json",
|
|
34
|
+
"introspection_endpoint": "YOUR_UNIAUTH_URL/api/v1/oauth2/introspect",
|
|
35
|
+
"response_types_supported": ["code"],
|
|
36
|
+
"grant_types_supported": ["authorization_code", "client_credentials", "refresh_token"],
|
|
37
|
+
"subject_types_supported": ["public"],
|
|
38
|
+
"id_token_signing_alg_values_supported": ["RS256"],
|
|
39
|
+
"scopes_supported": ["openid", "profile", "email", "phone"]
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API Endpoints
|
|
44
|
+
|
|
45
|
+
### 1. Authorization Code Flow
|
|
46
|
+
|
|
47
|
+
**Step 1: Redirect user to authorize**
|
|
48
|
+
```
|
|
49
|
+
GET YOUR_UNIAUTH_URL/api/v1/oauth2/authorize
|
|
50
|
+
?client_id=YOUR_CLIENT_ID
|
|
51
|
+
&redirect_uri=YOUR_REDIRECT_URI
|
|
52
|
+
&response_type=code
|
|
53
|
+
&scope=openid profile email
|
|
54
|
+
&state=random_csrf_state
|
|
55
|
+
&code_challenge=BASE64URL_CHALLENGE # PKCE (recommended)
|
|
56
|
+
&code_challenge_method=S256
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Step 2: Exchange code for tokens**
|
|
60
|
+
```http
|
|
61
|
+
POST YOUR_UNIAUTH_URL/api/v1/oauth2/token
|
|
62
|
+
Content-Type: application/json
|
|
63
|
+
|
|
64
|
+
{
|
|
65
|
+
"grant_type": "authorization_code",
|
|
66
|
+
"client_id": "YOUR_CLIENT_ID",
|
|
67
|
+
"client_secret": "YOUR_CLIENT_SECRET",
|
|
68
|
+
"code": "AUTHORIZATION_CODE",
|
|
69
|
+
"redirect_uri": "YOUR_REDIRECT_URI",
|
|
70
|
+
"code_verifier": "PKCE_VERIFIER"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Response:
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"access_token": "eyJ...",
|
|
78
|
+
"token_type": "Bearer",
|
|
79
|
+
"expires_in": 3600,
|
|
80
|
+
"refresh_token": "eyJ...",
|
|
81
|
+
"id_token": "eyJ..."
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Client Credentials Flow (Machine-to-Machine)
|
|
86
|
+
|
|
87
|
+
```http
|
|
88
|
+
POST YOUR_UNIAUTH_URL/api/v1/oauth2/token
|
|
89
|
+
Content-Type: application/json
|
|
90
|
+
|
|
91
|
+
{
|
|
92
|
+
"grant_type": "client_credentials",
|
|
93
|
+
"client_id": "YOUR_CLIENT_ID",
|
|
94
|
+
"client_secret": "YOUR_CLIENT_SECRET",
|
|
95
|
+
"scope": "read write"
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Token Introspection (RFC 7662)
|
|
100
|
+
|
|
101
|
+
```http
|
|
102
|
+
POST YOUR_UNIAUTH_URL/api/v1/oauth2/introspect
|
|
103
|
+
Authorization: Basic BASE64(client_id:client_secret)
|
|
104
|
+
Content-Type: application/json
|
|
105
|
+
|
|
106
|
+
{ "token": "ACCESS_TOKEN" }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 4. UserInfo Endpoint
|
|
110
|
+
|
|
111
|
+
```http
|
|
112
|
+
GET YOUR_UNIAUTH_URL/api/v1/oidc/userinfo
|
|
113
|
+
Authorization: Bearer ACCESS_TOKEN
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 5. JWKS (for local JWT verification)
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
GET YOUR_UNIAUTH_URL/.well-known/jwks.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Using the Client SDK (Optional)
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npm install @55387.ai/uniauth-client
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { UniAuthClient } from '@55387.ai/uniauth-client';
|
|
130
|
+
|
|
131
|
+
const client = new UniAuthClient({
|
|
132
|
+
baseUrl: 'YOUR_UNIAUTH_URL',
|
|
133
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Start OAuth2 flow with PKCE
|
|
137
|
+
const authUrl = await client.startOAuth2Flow({
|
|
138
|
+
redirectUri: 'YOUR_REDIRECT_URI',
|
|
139
|
+
scope: 'openid profile email',
|
|
140
|
+
usePKCE: true,
|
|
141
|
+
});
|
|
142
|
+
window.location.href = authUrl;
|
|
143
|
+
|
|
144
|
+
// On callback page — exchange code for tokens
|
|
145
|
+
const tokens = await client.exchangeOAuth2Code(
|
|
146
|
+
code, // from URL query param
|
|
147
|
+
'YOUR_REDIRECT_URI',
|
|
148
|
+
'YOUR_CLIENT_SECRET' // optional, for confidential clients
|
|
149
|
+
);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Requirements
|
|
153
|
+
|
|
154
|
+
1. **Authorization Code + PKCE**: Implement the full flow for browser-based apps (public clients). Always use PKCE.
|
|
155
|
+
|
|
156
|
+
2. **Client Credentials**: Implement M2M token acquisition for backend services that need to call UniAuth-protected APIs.
|
|
157
|
+
|
|
158
|
+
3. **Token Validation**: On your backend, validate tokens using either:
|
|
159
|
+
- **Introspection endpoint** (recommended for most cases)
|
|
160
|
+
- **JWKS-based local verification** (better performance, use JWKS endpoint)
|
|
161
|
+
|
|
162
|
+
4. **OIDC Discovery**: Auto-configure your app using the `.well-known/openid-configuration` endpoint instead of hardcoding URLs.
|
|
163
|
+
|
|
164
|
+
5. **State & CSRF**: Generate random `state` parameters and validate on callback.
|
|
165
|
+
|
|
166
|
+
6. **Token Storage**: Store access tokens securely. Refresh tokens before expiry.
|
|
167
|
+
|
|
168
|
+
7. **Environment Variables**:
|
|
169
|
+
```env
|
|
170
|
+
UNIAUTH_URL=YOUR_UNIAUTH_URL
|
|
171
|
+
UNIAUTH_CLIENT_ID=YOUR_CLIENT_ID
|
|
172
|
+
UNIAUTH_CLIENT_SECRET=YOUR_CLIENT_SECRET
|
|
173
|
+
UNIAUTH_REDIRECT_URI=YOUR_REDIRECT_URI
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Generate the complete implementation for my target platform/framework.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@55387.ai/uniauth-client",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"description": "UniAuth Frontend SDK - Phone, Email, SSO login for browser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"README.md"
|
|
11
|
+
"README.md",
|
|
12
|
+
"ai-prompts"
|
|
12
13
|
],
|
|
13
14
|
"exports": {
|
|
14
15
|
".": {
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@types/node": "^22.10.2",
|
|
34
|
+
"jsdom": "^27.3.0",
|
|
33
35
|
"tsup": "^8.3.5",
|
|
34
36
|
"typescript": "^5.7.2",
|
|
35
37
|
"vitest": "^2.1.9"
|
|
@@ -41,4 +43,4 @@
|
|
|
41
43
|
"login",
|
|
42
44
|
"sdk"
|
|
43
45
|
]
|
|
44
|
-
}
|
|
46
|
+
}
|