@vunexa/lixa 0.1.0 → 0.1.1
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 +3 -93
- package/README.template.md +360 -0
- package/docs/api/index.md +32 -0
- package/docs/api/lixa.iprovider.authorizationendpoint.md +13 -0
- package/docs/api/lixa.iprovider.md +100 -0
- package/docs/api/lixa.iprovider.tokenendpoint.md +13 -0
- package/docs/api/lixa.iprovider.userinfoendpoint.md +13 -0
- package/docs/api/lixa.lixa._constructor_.md +50 -0
- package/docs/api/lixa.lixa.generaterandomstate.md +23 -0
- package/docs/api/lixa.lixa.getauthurl.md +85 -0
- package/docs/api/lixa.lixa.handlecallback.md +73 -0
- package/docs/api/lixa.lixa.isproviderregistered.md +65 -0
- package/docs/api/lixa.lixa.md +164 -0
- package/docs/api/lixa.lixa.registerprovider.md +69 -0
- package/docs/api/lixa.lixaconfig.md +96 -0
- package/docs/api/lixa.lixaconfig.providers.md +13 -0
- package/docs/api/lixa.lixaconfig.sessionstrategy.md +13 -0
- package/docs/api/lixa.lixaconfig.statedao.md +13 -0
- package/docs/api/lixa.md +108 -0
- package/docs/api/lixa.providerconfig.clientid.md +13 -0
- package/docs/api/lixa.providerconfig.clientsecret.md +13 -0
- package/docs/api/lixa.providerconfig.extraconfig.md +13 -0
- package/docs/api/lixa.providerconfig.md +134 -0
- package/docs/api/lixa.providerconfig.redirecturi.md +13 -0
- package/docs/api/lixa.providerconfig.scopes.md +13 -0
- package/docs/api/lixa.session.md +77 -0
- package/docs/api/lixa.session.raw.md +13 -0
- package/docs/api/lixa.session.token.md +13 -0
- package/docs/api/lixa.sessionstrategy.createsession.md +56 -0
- package/docs/api/lixa.sessionstrategy.md +40 -0
- package/docs/images/account-linking.svg +1 -0
- package/docs/images/architecture.svg +1 -0
- package/docs/images/resource-connection.svg +1 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -28,36 +28,7 @@ A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library
|
|
|
28
28
|
|
|
29
29
|
## Architecture Overview
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
graph TD
|
|
33
|
-
User([User Client / Browser])
|
|
34
|
-
|
|
35
|
-
subgraph Lixa ["Lixa Core Engine"]
|
|
36
|
-
AuthNGuard["Primary AuthN Guard<br/>(Minimal Identity Scopes Only)"]
|
|
37
|
-
SessionMgr["Session Handler & Unified Session"]
|
|
38
|
-
AccountLinker["Account Linker<br/>(AUTO_LINK_BY_VERIFIED_EMAIL)"]
|
|
39
|
-
ResourceConn["Resource Connection API<br/>(Post-Login AuthZ)"]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
subgraph IdentityProviders ["Identity Providers (AuthN)"]
|
|
43
|
-
GoogleAuth["Google / OIDC"]
|
|
44
|
-
GitHubAuth["GitHub OAuth"]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
subgraph ResourceProviders ["Resource APIs (AuthZ)"]
|
|
48
|
-
GitHubAPI["GitHub API (repos, orgs)"]
|
|
49
|
-
GoogleDriveAPI["Google Drive API"]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
User -->|"1. Primary Login / Link Account"| AuthNGuard
|
|
53
|
-
AuthNGuard -->|"Request Identity"| IdentityProviders
|
|
54
|
-
IdentityProviders -->|"Tokens + UserInfo"| AccountLinker
|
|
55
|
-
AccountLinker -->|"Unified Session (session.accounts)"| SessionMgr
|
|
56
|
-
|
|
57
|
-
User -->|"2. Connect Resource API (Post-Login)"| ResourceConn
|
|
58
|
-
ResourceConn -->|"Request Permissions (repo, drive)"| ResourceProviders
|
|
59
|
-
ResourceProviders -->|"Resource Access Tokens"| SessionMgr
|
|
60
|
-
```
|
|
31
|
+

|
|
61
32
|
|
|
62
33
|
---
|
|
63
34
|
|
|
@@ -141,46 +112,7 @@ Lixa supports automatic identity merging for users signing in with different SSO
|
|
|
141
112
|
|
|
142
113
|
### Account Linking Sequence Diagram
|
|
143
114
|
|
|
144
|
-
|
|
145
|
-
sequenceDiagram
|
|
146
|
-
autonumber
|
|
147
|
-
actor User
|
|
148
|
-
participant App as Express Backend
|
|
149
|
-
participant Lixa as Lixa Engine
|
|
150
|
-
participant SessionStore as SessionStorage
|
|
151
|
-
participant Google as Google Identity
|
|
152
|
-
participant GitHub as GitHub Identity
|
|
153
|
-
|
|
154
|
-
Note over User, GitHub: 1. Primary Login with Google
|
|
155
|
-
User->>App: GET /auth/google
|
|
156
|
-
App->>Lixa: getAuthUrl('google')
|
|
157
|
-
Lixa-->>App: Redirect URL (openid, email, profile)
|
|
158
|
-
App-->>User: 302 Redirect to Google Consent
|
|
159
|
-
User->>Google: Grant Identity Consent
|
|
160
|
-
Google-->>App: GET /auth/google/callback?code=xxx
|
|
161
|
-
App->>Lixa: handleCallback({ provider: 'google', code })
|
|
162
|
-
Lixa->>Google: Exchange code for tokens
|
|
163
|
-
Lixa->>Lixa: extractUserInfo() -> alex@example.com (verified)
|
|
164
|
-
Lixa->>SessionStore: Save session (sessionId: 0x123...)
|
|
165
|
-
Lixa-->>App: Returns sessionId: 0x123...
|
|
166
|
-
App-->>User: Set Cookie session_id=0x123...
|
|
167
|
-
|
|
168
|
-
Note over User, GitHub: 2. Subsequent Login with GitHub (Same Email)
|
|
169
|
-
User->>App: GET /auth/github
|
|
170
|
-
App->>Lixa: getAuthUrl('github')
|
|
171
|
-
Lixa-->>App: Redirect URL (read:user, user:email)
|
|
172
|
-
App-->>User: 302 Redirect to GitHub Consent
|
|
173
|
-
User->>GitHub: Grant Identity Consent
|
|
174
|
-
GitHub-->>App: GET /auth/github/callback?code=yyy
|
|
175
|
-
App->>Lixa: handleCallback({ provider: 'github', code })
|
|
176
|
-
Lixa->>GitHub: Exchange code for tokens
|
|
177
|
-
Lixa->>Lixa: extractUserInfo() -> alex@example.com (verified)
|
|
178
|
-
Lixa->>SessionStore: getSessionByEmail("alex@example.com")
|
|
179
|
-
SessionStore-->>Lixa: Existing Session (sessionId: 0x123...)
|
|
180
|
-
Lixa->>Lixa: Merge github into session.accounts['github']
|
|
181
|
-
Lixa->>SessionStore: Save updated session (sessionId: 0x123...)
|
|
182
|
-
Lixa-->>App: Returns SAME sessionId: 0x123...
|
|
183
|
-
```
|
|
115
|
+

|
|
184
116
|
|
|
185
117
|
### Account Linking Configuration Modes
|
|
186
118
|
|
|
@@ -222,29 +154,7 @@ Primary authentication is strictly limited to identity scopes. To request third-
|
|
|
222
154
|
|
|
223
155
|
### Resource Connection Sequence Diagram
|
|
224
156
|
|
|
225
|
-
|
|
226
|
-
sequenceDiagram
|
|
227
|
-
autonumber
|
|
228
|
-
actor User
|
|
229
|
-
participant App as Express Backend
|
|
230
|
-
participant Lixa as Lixa Engine
|
|
231
|
-
participant SessionStore as SessionStorage
|
|
232
|
-
participant ResourceAPI as GitHub OAuth (Resource Scopes)
|
|
233
|
-
|
|
234
|
-
Note over User, ResourceAPI: Connect Resource API Post-Login
|
|
235
|
-
User->>App: POST /connect/github (Cookie: session_id=0x123...)
|
|
236
|
-
App->>Lixa: getResourceAuthUrl({ sessionId: '0x123...', provider: 'github', scopes: ['repo', 'read:org'] })
|
|
237
|
-
Lixa->>SessionStore: Validate active session
|
|
238
|
-
Lixa-->>App: Resource Authorization URL (scopes: repo read:org)
|
|
239
|
-
App-->>User: 302 Redirect to Resource Consent
|
|
240
|
-
User->>ResourceAPI: Grant Resource Consent (Repo Access)
|
|
241
|
-
ResourceAPI-->>App: GET /connect/github/callback?code=zzz&state=...
|
|
242
|
-
App->>Lixa: handleResourceCallback({ sessionId: '0x123...', provider: 'github', code })
|
|
243
|
-
Lixa->>ResourceAPI: Exchange code for Resource Access Token
|
|
244
|
-
Lixa->>SessionStore: Store under session.resources['github']
|
|
245
|
-
Lixa-->>App: Updated Session
|
|
246
|
-
App-->>User: Render Dashboard (Repo Access Granted)
|
|
247
|
-
```
|
|
157
|
+

|
|
248
158
|
|
|
249
159
|
### Resource Connection Usage Example
|
|
250
160
|
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# @vunexa/lixa
|
|
2
|
+
|
|
3
|
+
> Package is in active development.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@vunexa/lixa)
|
|
6
|
+
[](https://www.npmjs.com/package/@vunexa/lixa)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library for backend applications.
|
|
10
|
+
`@vunexa/lixa` simplifies multi-provider authentication (e.g. Google, GitHub, Microsoft), enforces strict **AuthN/AuthZ separation**, enables **multi-SSO account linking**, and provides a dedicated post-login **Resource Connection API**.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Strict AuthN / AuthZ Separation**: Primary login is automatically restricted to minimal identity scopes (`openid`, `email`, `profile`). Resource scopes are isolated to post-login connection.
|
|
17
|
+
- **Multi-SSO Account Linking**: Seamlessly merge accounts sharing the same verified email address under a single unified user session.
|
|
18
|
+
- **Post-Login Resource Connection API**: Connect third-party API providers (GitHub Repositories, Google Drive, Slack) post-authentication and manage resource tokens on the user session.
|
|
19
|
+
- **Multi-provider OAuth/OIDC support** with unified API.
|
|
20
|
+
- **Built-in providers** for Google, GitHub, and more via `@vunexa/lixa-providers`.
|
|
21
|
+
- **Custom provider support** with extensible provider interface.
|
|
22
|
+
- **Unified session management** via `SessionHandler` (generation + storage).
|
|
23
|
+
- **Unified state management** via `StateHandler` (PKCE + CSRF protection).
|
|
24
|
+
- **Automatic PKCE** (Proof Key for Code Exchange) for all OAuth flows.
|
|
25
|
+
- **TypeScript-first** with full type safety (zero `any` types).
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Architecture Overview
|
|
30
|
+
|
|
31
|
+
```mermaid
|
|
32
|
+
graph TD
|
|
33
|
+
User([User Client / Browser])
|
|
34
|
+
|
|
35
|
+
subgraph Lixa ["Lixa Core Engine"]
|
|
36
|
+
AuthNGuard["Primary AuthN Guard<br/>(Minimal Identity Scopes Only)"]
|
|
37
|
+
SessionMgr["Session Handler & Unified Session"]
|
|
38
|
+
AccountLinker["Account Linker<br/>(AUTO_LINK_BY_VERIFIED_EMAIL)"]
|
|
39
|
+
ResourceConn["Resource Connection API<br/>(Post-Login AuthZ)"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
subgraph IdentityProviders ["Identity Providers (AuthN)"]
|
|
43
|
+
GoogleAuth["Google / OIDC"]
|
|
44
|
+
GitHubAuth["GitHub OAuth"]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
subgraph ResourceProviders ["Resource APIs (AuthZ)"]
|
|
48
|
+
GitHubAPI["GitHub API (repos, orgs)"]
|
|
49
|
+
GoogleDriveAPI["Google Drive API"]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
User -->|"1. Primary Login / Link Account"| AuthNGuard
|
|
53
|
+
AuthNGuard -->|"Request Identity"| IdentityProviders
|
|
54
|
+
IdentityProviders -->|"Tokens + UserInfo"| AccountLinker
|
|
55
|
+
AccountLinker -->|"Unified Session (session.accounts)"| SessionMgr
|
|
56
|
+
|
|
57
|
+
User -->|"2. Connect Resource API (Post-Login)"| ResourceConn
|
|
58
|
+
ResourceConn -->|"Request Permissions (repo, drive)"| ResourceProviders
|
|
59
|
+
ResourceProviders -->|"Resource Access Tokens"| SessionMgr
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm install @vunexa/lixa @vunexa/lixa-providers
|
|
68
|
+
# or
|
|
69
|
+
yarn add @vunexa/lixa @vunexa/lixa-providers
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Quick Start
|
|
75
|
+
|
|
76
|
+
### 1. Configure Lixa with Account Linking & Providers
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { Lixa, AccountLinkingStrategy } from "@vunexa/lixa";
|
|
80
|
+
import { GoogleProvider, GithubProvider } from "@vunexa/lixa-providers";
|
|
81
|
+
|
|
82
|
+
export const lixa = new Lixa({
|
|
83
|
+
// Configure Multi-SSO Account Linking Strategy
|
|
84
|
+
accountLinking: {
|
|
85
|
+
mode: AccountLinkingStrategy.AUTO_LINK_BY_VERIFIED_EMAIL,
|
|
86
|
+
requireVerifiedEmail: true,
|
|
87
|
+
},
|
|
88
|
+
providers: {
|
|
89
|
+
google: {
|
|
90
|
+
provider: new GoogleProvider(),
|
|
91
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
92
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
93
|
+
redirectUri: "http://localhost:3000/auth/google/callback",
|
|
94
|
+
scopes: ["openid", "email", "profile"],
|
|
95
|
+
},
|
|
96
|
+
github: {
|
|
97
|
+
provider: new GithubProvider(),
|
|
98
|
+
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
99
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
100
|
+
redirectUri: "http://localhost:3000/auth/github/callback",
|
|
101
|
+
scopes: ["read:user", "user:email"],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 2. Primary Authentication & Callback
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// 1. Redirect to provider authorization URL
|
|
111
|
+
app.get("/auth/:provider", async (req, res) => {
|
|
112
|
+
const authUrl = await lixa.getAuthUrl(req.params.provider);
|
|
113
|
+
res.redirect(authUrl);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// 2. Handle provider callback
|
|
117
|
+
app.get("/auth/:provider/callback", async (req, res) => {
|
|
118
|
+
const { code, state } = req.query;
|
|
119
|
+
const provider = req.params.provider;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const sessionId = await lixa.handleCallback({
|
|
123
|
+
provider,
|
|
124
|
+
code: code as string,
|
|
125
|
+
state: state as string,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
res.cookie("session_id", sessionId, { httpOnly: true, secure: true });
|
|
129
|
+
res.redirect("/profile");
|
|
130
|
+
} catch (error) {
|
|
131
|
+
res.status(401).send("Authentication failed");
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Multi-SSO Account Linking
|
|
139
|
+
|
|
140
|
+
Lixa supports automatic identity merging for users signing in with different SSO providers (e.g. Google and GitHub) that share the same verified email address.
|
|
141
|
+
|
|
142
|
+
### Account Linking Sequence Diagram
|
|
143
|
+
|
|
144
|
+
```mermaid
|
|
145
|
+
sequenceDiagram
|
|
146
|
+
autonumber
|
|
147
|
+
actor User
|
|
148
|
+
participant App as Express Backend
|
|
149
|
+
participant Lixa as Lixa Engine
|
|
150
|
+
participant SessionStore as SessionStorage
|
|
151
|
+
participant Google as Google Identity
|
|
152
|
+
participant GitHub as GitHub Identity
|
|
153
|
+
|
|
154
|
+
Note over User, GitHub: 1. Primary Login with Google
|
|
155
|
+
User->>App: GET /auth/google
|
|
156
|
+
App->>Lixa: getAuthUrl('google')
|
|
157
|
+
Lixa-->>App: Redirect URL (openid, email, profile)
|
|
158
|
+
App-->>User: 302 Redirect to Google Consent
|
|
159
|
+
User->>Google: Grant Identity Consent
|
|
160
|
+
Google-->>App: GET /auth/google/callback?code=xxx
|
|
161
|
+
App->>Lixa: handleCallback({ provider: 'google', code })
|
|
162
|
+
Lixa->>Google: Exchange code for tokens
|
|
163
|
+
Lixa->>Lixa: extractUserInfo() -> alex@example.com (verified)
|
|
164
|
+
Lixa->>SessionStore: Save session (sessionId: 0x123...)
|
|
165
|
+
Lixa-->>App: Returns sessionId: 0x123...
|
|
166
|
+
App-->>User: Set Cookie session_id=0x123...
|
|
167
|
+
|
|
168
|
+
Note over User, GitHub: 2. Subsequent Login with GitHub (Same Email)
|
|
169
|
+
User->>App: GET /auth/github
|
|
170
|
+
App->>Lixa: getAuthUrl('github')
|
|
171
|
+
Lixa-->>App: Redirect URL (read:user, user:email)
|
|
172
|
+
App-->>User: 302 Redirect to GitHub Consent
|
|
173
|
+
User->>GitHub: Grant Identity Consent
|
|
174
|
+
GitHub-->>App: GET /auth/github/callback?code=yyy
|
|
175
|
+
App->>Lixa: handleCallback({ provider: 'github', code })
|
|
176
|
+
Lixa->>GitHub: Exchange code for tokens
|
|
177
|
+
Lixa->>Lixa: extractUserInfo() -> alex@example.com (verified)
|
|
178
|
+
Lixa->>SessionStore: getSessionByEmail("alex@example.com")
|
|
179
|
+
SessionStore-->>Lixa: Existing Session (sessionId: 0x123...)
|
|
180
|
+
Lixa->>Lixa: Merge github into session.accounts['github']
|
|
181
|
+
Lixa->>SessionStore: Save updated session (sessionId: 0x123...)
|
|
182
|
+
Lixa-->>App: Returns SAME sessionId: 0x123...
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Account Linking Configuration Modes
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { AccountLinkingStrategy } from "@vunexa/lixa";
|
|
189
|
+
|
|
190
|
+
// Mode 1: Auto-link by verified email (Recommended)
|
|
191
|
+
accountLinking: {
|
|
192
|
+
mode: AccountLinkingStrategy.AUTO_LINK_BY_VERIFIED_EMAIL,
|
|
193
|
+
requireVerifiedEmail: true,
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Mode 2: Treat provider logins as separate accounts
|
|
197
|
+
accountLinking: {
|
|
198
|
+
mode: AccountLinkingStrategy.ISOLATED,
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Explicit Account Linking & Unlinking APIs
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Explicitly link a new provider while authenticated
|
|
206
|
+
await lixa.linkAccount({
|
|
207
|
+
sessionId: req.cookies.session_id,
|
|
208
|
+
provider: "github",
|
|
209
|
+
code: req.query.code as string,
|
|
210
|
+
state: req.query.state as string,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Unlink a provider account
|
|
214
|
+
await lixa.unlinkAccount(req.cookies.session_id, "github");
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Post-Login Resource Connection API (AuthZ)
|
|
220
|
+
|
|
221
|
+
Primary authentication is strictly limited to identity scopes. To request third-party API permissions (such as GitHub Repositories or Google Drive), use Lixa's post-login **Resource Connection API**.
|
|
222
|
+
|
|
223
|
+
### Resource Connection Sequence Diagram
|
|
224
|
+
|
|
225
|
+
```mermaid
|
|
226
|
+
sequenceDiagram
|
|
227
|
+
autonumber
|
|
228
|
+
actor User
|
|
229
|
+
participant App as Express Backend
|
|
230
|
+
participant Lixa as Lixa Engine
|
|
231
|
+
participant SessionStore as SessionStorage
|
|
232
|
+
participant ResourceAPI as GitHub OAuth (Resource Scopes)
|
|
233
|
+
|
|
234
|
+
Note over User, ResourceAPI: Connect Resource API Post-Login
|
|
235
|
+
User->>App: POST /connect/github (Cookie: session_id=0x123...)
|
|
236
|
+
App->>Lixa: getResourceAuthUrl({ sessionId: '0x123...', provider: 'github', scopes: ['repo', 'read:org'] })
|
|
237
|
+
Lixa->>SessionStore: Validate active session
|
|
238
|
+
Lixa-->>App: Resource Authorization URL (scopes: repo read:org)
|
|
239
|
+
App-->>User: 302 Redirect to Resource Consent
|
|
240
|
+
User->>ResourceAPI: Grant Resource Consent (Repo Access)
|
|
241
|
+
ResourceAPI-->>App: GET /connect/github/callback?code=zzz&state=...
|
|
242
|
+
App->>Lixa: handleResourceCallback({ sessionId: '0x123...', provider: 'github', code })
|
|
243
|
+
Lixa->>ResourceAPI: Exchange code for Resource Access Token
|
|
244
|
+
Lixa->>SessionStore: Store under session.resources['github']
|
|
245
|
+
Lixa-->>App: Updated Session
|
|
246
|
+
App-->>User: Render Dashboard (Repo Access Granted)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Resource Connection Usage Example
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// 1. Generate Resource Authorization URL (Requires Active Session)
|
|
253
|
+
app.get("/connect/github", async (req, res) => {
|
|
254
|
+
const sessionId = req.cookies.session_id;
|
|
255
|
+
|
|
256
|
+
const resourceAuthUrl = await lixa.getResourceAuthUrl({
|
|
257
|
+
sessionId,
|
|
258
|
+
provider: "github",
|
|
259
|
+
scopes: ["repo", "read:org"], // Resource permissions requested post-login
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
res.redirect(resourceAuthUrl);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// 2. Handle Resource Callback
|
|
266
|
+
app.get("/connect/github/callback", async (req, res) => {
|
|
267
|
+
const sessionId = req.cookies.session_id;
|
|
268
|
+
|
|
269
|
+
const updatedSession = await lixa.handleResourceCallback({
|
|
270
|
+
sessionId,
|
|
271
|
+
provider: "github",
|
|
272
|
+
code: req.query.code as string,
|
|
273
|
+
state: req.query.state as string,
|
|
274
|
+
scopes: ["repo", "read:org"],
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
res.redirect("/dashboard");
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// 3. Query Connected Resource Access Token
|
|
281
|
+
app.get("/api/github/repos", async (req, res) => {
|
|
282
|
+
const resource = await lixa.getConnectedResource(req.cookies.session_id, "github");
|
|
283
|
+
|
|
284
|
+
if (!resource) {
|
|
285
|
+
return res.status(403).json({ error: "GitHub resource not connected" });
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Call GitHub API with resource access token
|
|
289
|
+
const response = await fetch("https://api.github.com/user/repos", {
|
|
290
|
+
headers: { Authorization: `Bearer ${resource.accessToken}` },
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const repos = await response.json();
|
|
294
|
+
res.json(repos);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// 4. Disconnect Resource Provider
|
|
298
|
+
app.delete("/connect/github", async (req, res) => {
|
|
299
|
+
await lixa.disconnectResource(req.cookies.session_id, "github");
|
|
300
|
+
res.json({ success: true });
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Session Interface Structure
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
export interface Session<TRaw = OAuthTokenResponse> {
|
|
310
|
+
/** Unique session ID generated by Lixa */
|
|
311
|
+
id?: string;
|
|
312
|
+
|
|
313
|
+
/** Primary access token or session token */
|
|
314
|
+
token: string;
|
|
315
|
+
|
|
316
|
+
/** Unified user ID across linked accounts */
|
|
317
|
+
userId?: string;
|
|
318
|
+
|
|
319
|
+
/** Primary user email */
|
|
320
|
+
email?: string;
|
|
321
|
+
|
|
322
|
+
/** Current active auth provider */
|
|
323
|
+
provider?: string;
|
|
324
|
+
|
|
325
|
+
/** Linked SSO provider accounts (AuthN) */
|
|
326
|
+
accounts?: Record<string, LinkedAccount>;
|
|
327
|
+
|
|
328
|
+
/** Connected third-party resource provider tokens (AuthZ) */
|
|
329
|
+
resources?: Record<string, ConnectedResource>;
|
|
330
|
+
|
|
331
|
+
/** Full raw token response from provider */
|
|
332
|
+
raw: TRaw;
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### `LinkedAccount` vs `ConnectedResource`
|
|
337
|
+
|
|
338
|
+
| Concept | Purpose | Scopes Allowed | Stored Location |
|
|
339
|
+
| :--- | :--- | :--- | :--- |
|
|
340
|
+
| **`LinkedAccount`** | Identity verification & multi-SSO merging (**AuthN**) | Minimal identity scopes (`openid`, `email`, `read:user`) | `session.accounts[provider]` |
|
|
341
|
+
| **`ConnectedResource`** | External API resource access (**AuthZ**) | Resource permissions (`repo`, `drive.readonly`) | `session.resources[provider]` |
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## User Info Utilities
|
|
346
|
+
|
|
347
|
+
Lixa provides utilities to extract user information from OAuth tokens:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import { extractUserInfo, type UserInfo } from "@vunexa/lixa";
|
|
351
|
+
|
|
352
|
+
const { userInfo } = await extractUserInfo(tokenData, providerMetadata);
|
|
353
|
+
console.log(userInfo.email, userInfo.name);
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md)
|
|
4
|
+
|
|
5
|
+
## API Reference
|
|
6
|
+
|
|
7
|
+
## Packages
|
|
8
|
+
|
|
9
|
+
<table><thead><tr><th>
|
|
10
|
+
|
|
11
|
+
Package
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
</th><th>
|
|
15
|
+
|
|
16
|
+
Description
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
</th></tr></thead>
|
|
20
|
+
<tbody><tr><td>
|
|
21
|
+
|
|
22
|
+
[@vunexa/lixa](./lixa.md)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
</td><td>
|
|
26
|
+
|
|
27
|
+
A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library for backend applications.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
</td></tr>
|
|
31
|
+
</tbody></table>
|
|
32
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@vunexa/lixa](./lixa.md) > [IProvider](./lixa.iprovider.md) > [authorizationEndpoint](./lixa.iprovider.authorizationendpoint.md)
|
|
4
|
+
|
|
5
|
+
## IProvider.authorizationEndpoint property
|
|
6
|
+
|
|
7
|
+
The OAuth authorization endpoint URL
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
authorizationEndpoint: string;
|
|
13
|
+
```
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@vunexa/lixa](./lixa.md) > [IProvider](./lixa.iprovider.md)
|
|
4
|
+
|
|
5
|
+
## IProvider interface
|
|
6
|
+
|
|
7
|
+
Interface for OAuth provider implementations.
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
interface IProvider
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Remarks
|
|
16
|
+
|
|
17
|
+
Implement this interface to add support for custom OAuth providers.
|
|
18
|
+
|
|
19
|
+
## Properties
|
|
20
|
+
|
|
21
|
+
<table><thead><tr><th>
|
|
22
|
+
|
|
23
|
+
Property
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
</th><th>
|
|
27
|
+
|
|
28
|
+
Modifiers
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
</th><th>
|
|
32
|
+
|
|
33
|
+
Type
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
</th><th>
|
|
37
|
+
|
|
38
|
+
Description
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
</th></tr></thead>
|
|
42
|
+
<tbody><tr><td>
|
|
43
|
+
|
|
44
|
+
[authorizationEndpoint](./lixa.iprovider.authorizationendpoint.md)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
</td><td>
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
</td><td>
|
|
51
|
+
|
|
52
|
+
string
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
</td><td>
|
|
56
|
+
|
|
57
|
+
The OAuth authorization endpoint URL
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
</td></tr>
|
|
61
|
+
<tr><td>
|
|
62
|
+
|
|
63
|
+
[tokenEndpoint](./lixa.iprovider.tokenendpoint.md)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
</td><td>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
</td><td>
|
|
70
|
+
|
|
71
|
+
string
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
</td><td>
|
|
75
|
+
|
|
76
|
+
The OAuth token exchange endpoint URL
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
</td></tr>
|
|
80
|
+
<tr><td>
|
|
81
|
+
|
|
82
|
+
[userInfoEndpoint](./lixa.iprovider.userinfoendpoint.md)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
</td><td>
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
</td><td>
|
|
89
|
+
|
|
90
|
+
string
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
</td><td>
|
|
94
|
+
|
|
95
|
+
The user information endpoint URL
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
</td></tr>
|
|
99
|
+
</tbody></table>
|
|
100
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@vunexa/lixa](./lixa.md) > [IProvider](./lixa.iprovider.md) > [tokenEndpoint](./lixa.iprovider.tokenendpoint.md)
|
|
4
|
+
|
|
5
|
+
## IProvider.tokenEndpoint property
|
|
6
|
+
|
|
7
|
+
The OAuth token exchange endpoint URL
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
tokenEndpoint: string;
|
|
13
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@vunexa/lixa](./lixa.md) > [IProvider](./lixa.iprovider.md) > [userInfoEndpoint](./lixa.iprovider.userinfoendpoint.md)
|
|
4
|
+
|
|
5
|
+
## IProvider.userInfoEndpoint property
|
|
6
|
+
|
|
7
|
+
The user information endpoint URL
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
userInfoEndpoint: string;
|
|
13
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
2
|
+
|
|
3
|
+
[Home](./index.md) > [@vunexa/lixa](./lixa.md) > [Lixa](./lixa.lixa.md) > [(constructor)](./lixa.lixa._constructor_.md)
|
|
4
|
+
|
|
5
|
+
## Lixa.(constructor)
|
|
6
|
+
|
|
7
|
+
Creates a new Lixa instance with the provided configuration.
|
|
8
|
+
|
|
9
|
+
**Signature:**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
constructor(config: LixaConfig);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
<table><thead><tr><th>
|
|
18
|
+
|
|
19
|
+
Parameter
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
</th><th>
|
|
23
|
+
|
|
24
|
+
Type
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
</th><th>
|
|
28
|
+
|
|
29
|
+
Description
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
</th></tr></thead>
|
|
33
|
+
<tbody><tr><td>
|
|
34
|
+
|
|
35
|
+
config
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
</td><td>
|
|
39
|
+
|
|
40
|
+
[LixaConfig](./lixa.lixaconfig.md)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
</td><td>
|
|
44
|
+
|
|
45
|
+
The configuration object containing provider settings and optional session strategy
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
</td></tr>
|
|
49
|
+
</tbody></table>
|
|
50
|
+
|