@vunexa/lixa 0.1.6-alpha.3 → 0.1.6-alpha.4
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 +113 -3
- package/README.template.md +113 -3
- package/dist/dao/types.d.ts +47 -0
- package/dist/dao/types.d.ts.map +1 -1
- package/dist/export-types/index.d.ts +95 -5
- package/dist/index.cjs +185 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -12
- package/dist/index.js.map +1 -1
- package/dist/lixa.d.ts +37 -5
- package/dist/lixa.d.ts.map +1 -1
- package/dist/models/session.d.ts +2 -0
- package/dist/models/session.d.ts.map +1 -1
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -187,15 +187,16 @@ app.get("/connect/github/callback", async (req, res) => {
|
|
|
187
187
|
res.redirect("/dashboard");
|
|
188
188
|
});
|
|
189
189
|
|
|
190
|
-
// 3. Query Connected Resource Access Token
|
|
190
|
+
// 3. Query Connected Resource Access Token (Auto-Refreshes Expired Tokens)
|
|
191
191
|
app.get("/api/github/repos", async (req, res) => {
|
|
192
|
+
// Queries by active session OR user ID, auto-refreshing expired access tokens
|
|
192
193
|
const resource = await lixa.getConnectedResource(req.cookies.session_id, "github");
|
|
193
194
|
|
|
194
195
|
if (!resource) {
|
|
195
196
|
return res.status(403).json({ error: "GitHub resource not connected" });
|
|
196
197
|
}
|
|
197
198
|
|
|
198
|
-
// Call GitHub API with resource access token
|
|
199
|
+
// Call GitHub API with active resource access token
|
|
199
200
|
const response = await fetch("https://api.github.com/user/repos", {
|
|
200
201
|
headers: { Authorization: `Bearer ${resource.accessToken}` },
|
|
201
202
|
});
|
|
@@ -204,7 +205,10 @@ app.get("/api/github/repos", async (req, res) => {
|
|
|
204
205
|
res.json(repos);
|
|
205
206
|
});
|
|
206
207
|
|
|
207
|
-
// 4.
|
|
208
|
+
// 4. Query Resource Directly by User ID (e.g. inside background cron jobs or webhooks)
|
|
209
|
+
const githubResource = await lixa.getUserResource(userId, "github");
|
|
210
|
+
|
|
211
|
+
// 5. Disconnect Resource Provider
|
|
208
212
|
app.delete("/connect/github", async (req, res) => {
|
|
209
213
|
await lixa.disconnectResource(req.cookies.session_id, "github");
|
|
210
214
|
res.json({ success: true });
|
|
@@ -503,7 +507,113 @@ export const lixa = new Lixa({
|
|
|
503
507
|
"connectedAt": 1771657300000
|
|
504
508
|
}
|
|
505
509
|
}
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## Custom Resource Storage Implementation (`ResourceStorage`)
|
|
513
|
+
|
|
514
|
+
While `SessionStorage` manages short-lived user authentication sessions (indexed by `sessionId`), **`ResourceStorage`** manages long-lived third-party API tokens (**AuthZ**) bound directly to a **User ID** (or Email). This ensures that third-party credentials (such as GitHub Repositories or Google Drive) persist across session expirations and logouts.
|
|
515
|
+
|
|
516
|
+
### `ResourceStorage` Interface
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
export interface ResourceStorage {
|
|
520
|
+
saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void>;
|
|
521
|
+
getResource(userId: string, provider: string): Promise<ConnectedResource | null>;
|
|
522
|
+
getUserResources(userId: string): Promise<Record<string, ConnectedResource>>;
|
|
523
|
+
deleteResource(userId: string, provider: string): Promise<void>;
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### 1. SQLite Resource Storage (`better-sqlite3`)
|
|
528
|
+
|
|
529
|
+
#### Table Schema (SQL DDL)
|
|
530
|
+
|
|
531
|
+
```sql
|
|
532
|
+
CREATE TABLE IF NOT EXISTS user_resources (
|
|
533
|
+
user_id TEXT NOT NULL,
|
|
534
|
+
provider TEXT NOT NULL,
|
|
535
|
+
data TEXT NOT NULL,
|
|
536
|
+
updated_at INTEGER NOT NULL,
|
|
537
|
+
PRIMARY KEY (user_id, provider)
|
|
538
|
+
);
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
#### TypeScript Implementation
|
|
542
|
+
|
|
543
|
+
```typescript
|
|
544
|
+
import Database from "better-sqlite3";
|
|
545
|
+
import { Lixa, type ResourceStorage, type ConnectedResource } from "@vunexa/lixa";
|
|
546
|
+
|
|
547
|
+
export class SqliteResourceStorage implements ResourceStorage {
|
|
548
|
+
private db = new Database("lixa_resources.db");
|
|
549
|
+
|
|
550
|
+
constructor() {
|
|
551
|
+
this.db.exec(`
|
|
552
|
+
CREATE TABLE IF NOT EXISTS user_resources (
|
|
553
|
+
user_id TEXT NOT NULL,
|
|
554
|
+
provider TEXT NOT NULL,
|
|
555
|
+
data TEXT NOT NULL,
|
|
556
|
+
updated_at INTEGER NOT NULL,
|
|
557
|
+
PRIMARY KEY (user_id, provider)
|
|
558
|
+
);
|
|
559
|
+
`);
|
|
506
560
|
}
|
|
561
|
+
|
|
562
|
+
async saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void> {
|
|
563
|
+
const stmt = this.db.prepare(`
|
|
564
|
+
INSERT INTO user_resources (user_id, provider, data, updated_at)
|
|
565
|
+
VALUES (?, ?, ?, ?)
|
|
566
|
+
ON CONFLICT(user_id, provider) DO UPDATE SET
|
|
567
|
+
data = excluded.data,
|
|
568
|
+
updated_at = excluded.updated_at
|
|
569
|
+
`);
|
|
570
|
+
stmt.run(userId, provider.toLowerCase(), JSON.stringify(resource), Date.now());
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
async getResource(userId: string, provider: string): Promise<ConnectedResource | null> {
|
|
574
|
+
const stmt = this.db.prepare(`SELECT data FROM user_resources WHERE user_id = ? AND provider = ?`);
|
|
575
|
+
const row = stmt.get(userId, provider.toLowerCase()) as { data: string } | undefined;
|
|
576
|
+
return row ? (JSON.parse(row.data) as ConnectedResource) : null;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
async getUserResources(userId: string): Promise<Record<string, ConnectedResource>> {
|
|
580
|
+
const stmt = this.db.prepare(`SELECT provider, data FROM user_resources WHERE user_id = ?`);
|
|
581
|
+
const rows = stmt.all(userId) as Array<{ provider: string; data: string }>;
|
|
582
|
+
const result: Record<string, ConnectedResource> = {};
|
|
583
|
+
for (const r of rows) {
|
|
584
|
+
result[r.provider] = JSON.parse(r.data);
|
|
585
|
+
}
|
|
586
|
+
return result;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
async deleteResource(userId: string, provider: string): Promise<void> {
|
|
590
|
+
const stmt = this.db.prepare(`DELETE FROM user_resources WHERE user_id = ? AND provider = ?`);
|
|
591
|
+
stmt.run(userId, provider.toLowerCase());
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Pass to Lixa instance via resourceHandler
|
|
596
|
+
export const lixa = new Lixa({
|
|
597
|
+
resourceHandler: {
|
|
598
|
+
resourceStorage: new SqliteResourceStorage(),
|
|
599
|
+
},
|
|
600
|
+
providers: { /* ... */ },
|
|
601
|
+
});
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
### 2. Querying Connected Resources Directly by User ID
|
|
605
|
+
|
|
606
|
+
`ResourceStorage` enables background workers, cron jobs, and webhooks to access third-party API credentials by `userId` without an active HTTP session:
|
|
607
|
+
|
|
608
|
+
```typescript
|
|
609
|
+
// Background worker querying user's GitHub Repos token
|
|
610
|
+
const githubResource = await lixa.getUserResource(user.id, "github");
|
|
611
|
+
|
|
612
|
+
if (githubResource) {
|
|
613
|
+
// Lixa auto-refreshes expired access tokens transparently!
|
|
614
|
+
const response = await fetch("https://api.github.com/user/repos", {
|
|
615
|
+
headers: { Authorization: `Bearer ${githubResource.accessToken}` },
|
|
616
|
+
});
|
|
507
617
|
}
|
|
508
618
|
```
|
|
509
619
|
|
package/README.template.md
CHANGED
|
@@ -277,15 +277,16 @@ app.get("/connect/github/callback", async (req, res) => {
|
|
|
277
277
|
res.redirect("/dashboard");
|
|
278
278
|
});
|
|
279
279
|
|
|
280
|
-
// 3. Query Connected Resource Access Token
|
|
280
|
+
// 3. Query Connected Resource Access Token (Auto-Refreshes Expired Tokens)
|
|
281
281
|
app.get("/api/github/repos", async (req, res) => {
|
|
282
|
+
// Queries by active session OR user ID, auto-refreshing expired access tokens
|
|
282
283
|
const resource = await lixa.getConnectedResource(req.cookies.session_id, "github");
|
|
283
284
|
|
|
284
285
|
if (!resource) {
|
|
285
286
|
return res.status(403).json({ error: "GitHub resource not connected" });
|
|
286
287
|
}
|
|
287
288
|
|
|
288
|
-
// Call GitHub API with resource access token
|
|
289
|
+
// Call GitHub API with active resource access token
|
|
289
290
|
const response = await fetch("https://api.github.com/user/repos", {
|
|
290
291
|
headers: { Authorization: `Bearer ${resource.accessToken}` },
|
|
291
292
|
});
|
|
@@ -294,7 +295,10 @@ app.get("/api/github/repos", async (req, res) => {
|
|
|
294
295
|
res.json(repos);
|
|
295
296
|
});
|
|
296
297
|
|
|
297
|
-
// 4.
|
|
298
|
+
// 4. Query Resource Directly by User ID (e.g. inside background cron jobs or webhooks)
|
|
299
|
+
const githubResource = await lixa.getUserResource(userId, "github");
|
|
300
|
+
|
|
301
|
+
// 5. Disconnect Resource Provider
|
|
298
302
|
app.delete("/connect/github", async (req, res) => {
|
|
299
303
|
await lixa.disconnectResource(req.cookies.session_id, "github");
|
|
300
304
|
res.json({ success: true });
|
|
@@ -593,7 +597,113 @@ export const lixa = new Lixa({
|
|
|
593
597
|
"connectedAt": 1771657300000
|
|
594
598
|
}
|
|
595
599
|
}
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## Custom Resource Storage Implementation (`ResourceStorage`)
|
|
603
|
+
|
|
604
|
+
While `SessionStorage` manages short-lived user authentication sessions (indexed by `sessionId`), **`ResourceStorage`** manages long-lived third-party API tokens (**AuthZ**) bound directly to a **User ID** (or Email). This ensures that third-party credentials (such as GitHub Repositories or Google Drive) persist across session expirations and logouts.
|
|
605
|
+
|
|
606
|
+
### `ResourceStorage` Interface
|
|
607
|
+
|
|
608
|
+
```typescript
|
|
609
|
+
export interface ResourceStorage {
|
|
610
|
+
saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void>;
|
|
611
|
+
getResource(userId: string, provider: string): Promise<ConnectedResource | null>;
|
|
612
|
+
getUserResources(userId: string): Promise<Record<string, ConnectedResource>>;
|
|
613
|
+
deleteResource(userId: string, provider: string): Promise<void>;
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### 1. SQLite Resource Storage (`better-sqlite3`)
|
|
618
|
+
|
|
619
|
+
#### Table Schema (SQL DDL)
|
|
620
|
+
|
|
621
|
+
```sql
|
|
622
|
+
CREATE TABLE IF NOT EXISTS user_resources (
|
|
623
|
+
user_id TEXT NOT NULL,
|
|
624
|
+
provider TEXT NOT NULL,
|
|
625
|
+
data TEXT NOT NULL,
|
|
626
|
+
updated_at INTEGER NOT NULL,
|
|
627
|
+
PRIMARY KEY (user_id, provider)
|
|
628
|
+
);
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
#### TypeScript Implementation
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
import Database from "better-sqlite3";
|
|
635
|
+
import { Lixa, type ResourceStorage, type ConnectedResource } from "@vunexa/lixa";
|
|
636
|
+
|
|
637
|
+
export class SqliteResourceStorage implements ResourceStorage {
|
|
638
|
+
private db = new Database("lixa_resources.db");
|
|
639
|
+
|
|
640
|
+
constructor() {
|
|
641
|
+
this.db.exec(`
|
|
642
|
+
CREATE TABLE IF NOT EXISTS user_resources (
|
|
643
|
+
user_id TEXT NOT NULL,
|
|
644
|
+
provider TEXT NOT NULL,
|
|
645
|
+
data TEXT NOT NULL,
|
|
646
|
+
updated_at INTEGER NOT NULL,
|
|
647
|
+
PRIMARY KEY (user_id, provider)
|
|
648
|
+
);
|
|
649
|
+
`);
|
|
596
650
|
}
|
|
651
|
+
|
|
652
|
+
async saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void> {
|
|
653
|
+
const stmt = this.db.prepare(`
|
|
654
|
+
INSERT INTO user_resources (user_id, provider, data, updated_at)
|
|
655
|
+
VALUES (?, ?, ?, ?)
|
|
656
|
+
ON CONFLICT(user_id, provider) DO UPDATE SET
|
|
657
|
+
data = excluded.data,
|
|
658
|
+
updated_at = excluded.updated_at
|
|
659
|
+
`);
|
|
660
|
+
stmt.run(userId, provider.toLowerCase(), JSON.stringify(resource), Date.now());
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
async getResource(userId: string, provider: string): Promise<ConnectedResource | null> {
|
|
664
|
+
const stmt = this.db.prepare(`SELECT data FROM user_resources WHERE user_id = ? AND provider = ?`);
|
|
665
|
+
const row = stmt.get(userId, provider.toLowerCase()) as { data: string } | undefined;
|
|
666
|
+
return row ? (JSON.parse(row.data) as ConnectedResource) : null;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
async getUserResources(userId: string): Promise<Record<string, ConnectedResource>> {
|
|
670
|
+
const stmt = this.db.prepare(`SELECT provider, data FROM user_resources WHERE user_id = ?`);
|
|
671
|
+
const rows = stmt.all(userId) as Array<{ provider: string; data: string }>;
|
|
672
|
+
const result: Record<string, ConnectedResource> = {};
|
|
673
|
+
for (const r of rows) {
|
|
674
|
+
result[r.provider] = JSON.parse(r.data);
|
|
675
|
+
}
|
|
676
|
+
return result;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
async deleteResource(userId: string, provider: string): Promise<void> {
|
|
680
|
+
const stmt = this.db.prepare(`DELETE FROM user_resources WHERE user_id = ? AND provider = ?`);
|
|
681
|
+
stmt.run(userId, provider.toLowerCase());
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Pass to Lixa instance via resourceHandler
|
|
686
|
+
export const lixa = new Lixa({
|
|
687
|
+
resourceHandler: {
|
|
688
|
+
resourceStorage: new SqliteResourceStorage(),
|
|
689
|
+
},
|
|
690
|
+
providers: { /* ... */ },
|
|
691
|
+
});
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### 2. Querying Connected Resources Directly by User ID
|
|
695
|
+
|
|
696
|
+
`ResourceStorage` enables background workers, cron jobs, and webhooks to access third-party API credentials by `userId` without an active HTTP session:
|
|
697
|
+
|
|
698
|
+
```typescript
|
|
699
|
+
// Background worker querying user's GitHub Repos token
|
|
700
|
+
const githubResource = await lixa.getUserResource(user.id, "github");
|
|
701
|
+
|
|
702
|
+
if (githubResource) {
|
|
703
|
+
// Lixa auto-refreshes expired access tokens transparently!
|
|
704
|
+
const response = await fetch("https://api.github.com/user/repos", {
|
|
705
|
+
headers: { Authorization: `Bearer ${githubResource.accessToken}` },
|
|
706
|
+
});
|
|
597
707
|
}
|
|
598
708
|
```
|
|
599
709
|
|
package/dist/dao/types.d.ts
CHANGED
|
@@ -220,6 +220,53 @@ export interface SessionStorage {
|
|
|
220
220
|
session: T;
|
|
221
221
|
} | null>;
|
|
222
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Resource storage operations interface.
|
|
225
|
+
*
|
|
226
|
+
* @remarks
|
|
227
|
+
* Manages long-lived third-party resource provider tokens (AuthZ) bound to a user account
|
|
228
|
+
* (User ID or Email), independent of short-lived user sessions.
|
|
229
|
+
*
|
|
230
|
+
* @public
|
|
231
|
+
*/
|
|
232
|
+
export interface ResourceStorage {
|
|
233
|
+
/**
|
|
234
|
+
* Saves a connected resource token for a user.
|
|
235
|
+
*
|
|
236
|
+
* @param userId - Unique user identifier or email
|
|
237
|
+
* @param provider - Resource provider name (e.g. 'github', 'google')
|
|
238
|
+
* @param resource - Connected resource details including access & refresh tokens
|
|
239
|
+
*/
|
|
240
|
+
saveResource(userId: string, provider: string, resource: import("../models/session").ConnectedResource): Promise<void>;
|
|
241
|
+
/**
|
|
242
|
+
* Retrieves a connected resource token for a user.
|
|
243
|
+
*
|
|
244
|
+
* @param userId - Unique user identifier or email
|
|
245
|
+
* @param provider - Resource provider name
|
|
246
|
+
*/
|
|
247
|
+
getResource(userId: string, provider: string): Promise<import("../models/session").ConnectedResource | null>;
|
|
248
|
+
/**
|
|
249
|
+
* Retrieves all connected resources for a user.
|
|
250
|
+
*
|
|
251
|
+
* @param userId - Unique user identifier or email
|
|
252
|
+
*/
|
|
253
|
+
getUserResources(userId: string): Promise<Record<string, import("../models/session").ConnectedResource>>;
|
|
254
|
+
/**
|
|
255
|
+
* Deletes a connected resource token for a user.
|
|
256
|
+
*
|
|
257
|
+
* @param userId - Unique user identifier or email
|
|
258
|
+
* @param provider - Resource provider name
|
|
259
|
+
*/
|
|
260
|
+
deleteResource(userId: string, provider: string): Promise<void>;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Resource handler configuration.
|
|
264
|
+
*
|
|
265
|
+
* @public
|
|
266
|
+
*/
|
|
267
|
+
export interface ResourceHandler {
|
|
268
|
+
resourceStorage?: ResourceStorage;
|
|
269
|
+
}
|
|
223
270
|
/**
|
|
224
271
|
* Session handler for OAuth authentication.
|
|
225
272
|
*
|
package/dist/dao/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAEnD;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,aAAa,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAE9E;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,SAAS,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvG;;;;;OAKG;IACH,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpE;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACzG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgDG;IACH,eAAe,CAAC,CAAC,CAAC,SAAS,OAAO,EAChC,SAAS,EAAE,OAAO,mBAAmB,EAAE,kBAAkB,EACzD,gBAAgB,EAAE,OAAO,mBAAmB,EAAE,gBAAgB,GAC7D,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;OAKG;IACH,eAAe,CAAC,CAAC,CAAC,SAAS,OAAO,EAChC,SAAS,EAAE,OAAO,mBAAmB,EAAE,kBAAkB,EACzD,gBAAgB,EAAE,OAAO,mBAAmB,EAAE,gBAAgB,GAC7D,OAAO,CAAC,CAAC,CAAC,CAAC;CACf"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -141,6 +141,8 @@ export declare interface ConnectedResource {
|
|
|
141
141
|
accessToken: string;
|
|
142
142
|
/** Optional refresh token for offline resource access */
|
|
143
143
|
refreshToken?: string | undefined;
|
|
144
|
+
/** Unix timestamp in milliseconds when the resource access token expires */
|
|
145
|
+
expiresAt?: number | undefined;
|
|
144
146
|
/** Resource scopes granted by the user */
|
|
145
147
|
scopes: string[];
|
|
146
148
|
/** Full raw token response from provider */
|
|
@@ -437,6 +439,7 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
437
439
|
private config;
|
|
438
440
|
private stateHandler;
|
|
439
441
|
private sessionHandler;
|
|
442
|
+
private resourceHandler;
|
|
440
443
|
private debug;
|
|
441
444
|
/**
|
|
442
445
|
* Creates a new Lixa instance with the provided configuration.
|
|
@@ -749,6 +752,12 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
749
752
|
* @param params - Object containing sessionId, provider, code, state, and requested scopes
|
|
750
753
|
* @returns Updated Session containing stored resource tokens under session.resources[provider]
|
|
751
754
|
*/
|
|
755
|
+
private static userResourceStore;
|
|
756
|
+
static LOCAL_RESOURCE_HANDLER: ResourceHandler;
|
|
757
|
+
private getUserKeyFromSession;
|
|
758
|
+
/**
|
|
759
|
+
* Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
|
|
760
|
+
*/
|
|
752
761
|
handleResourceCallback(params: {
|
|
753
762
|
sessionId: string;
|
|
754
763
|
provider: ConfiguredProviderKey<TConfig> | string;
|
|
@@ -757,17 +766,41 @@ export declare class Lixa<TConfig extends LixaConfig<Record<string, ProviderConf
|
|
|
757
766
|
scopes?: string[];
|
|
758
767
|
}): Promise<Session>;
|
|
759
768
|
/**
|
|
760
|
-
* Retrieves a connected resource
|
|
769
|
+
* Retrieves a connected resource for a specific User ID / Email directly (independent of session IDs).
|
|
770
|
+
* Automatically refreshes expired access tokens if a refresh token is present.
|
|
771
|
+
*
|
|
772
|
+
* @param userIdOrEmail - User identifier or email
|
|
773
|
+
* @param provider - Resource provider identifier (e.g. 'github', 'google')
|
|
774
|
+
*/
|
|
775
|
+
getUserResource(userIdOrEmail: string, provider: string): Promise<ConnectedResource | null>;
|
|
776
|
+
/**
|
|
777
|
+
* Retrieves all connected resources for a specific User ID / Email.
|
|
778
|
+
*/
|
|
779
|
+
getUserResources(userIdOrEmail: string): Promise<Record<string, ConnectedResource>>;
|
|
780
|
+
/**
|
|
781
|
+
* Retrieves a connected resource provider token for an active session, auto-refreshing expired tokens if possible.
|
|
761
782
|
*
|
|
762
783
|
* @param sessionId - Active session ID
|
|
763
|
-
* @param provider - Provider identifier (e.g. 'github')
|
|
784
|
+
* @param provider - Provider identifier (e.g. 'github', 'google')
|
|
764
785
|
*/
|
|
765
786
|
getConnectedResource(sessionId: string, provider: string): Promise<ConnectedResource | null>;
|
|
766
787
|
/**
|
|
767
|
-
*
|
|
788
|
+
* Refreshes a user's resource access token using its refresh token.
|
|
768
789
|
*
|
|
769
|
-
* @param
|
|
770
|
-
* @param provider - Provider identifier
|
|
790
|
+
* @param userIdOrEmail - User identifier or email
|
|
791
|
+
* @param provider - Provider identifier (e.g. 'google', 'github')
|
|
792
|
+
*/
|
|
793
|
+
refreshUserResourceToken(userIdOrEmail: string, provider: string, existingResource?: ConnectedResource): Promise<ConnectedResource>;
|
|
794
|
+
/**
|
|
795
|
+
* Refreshes a connected resource access token for an active session.
|
|
796
|
+
*/
|
|
797
|
+
refreshResourceToken(sessionId: string, provider: string): Promise<ConnectedResource>;
|
|
798
|
+
/**
|
|
799
|
+
* Disconnects a resource provider for a specific User ID / Email.
|
|
800
|
+
*/
|
|
801
|
+
disconnectUserResource(userIdOrEmail: string, provider: string): Promise<boolean>;
|
|
802
|
+
/**
|
|
803
|
+
* Disconnects a resource provider from an active session and user account.
|
|
771
804
|
*/
|
|
772
805
|
disconnectResource(sessionId: string, provider: string): Promise<boolean>;
|
|
773
806
|
fetchSessionInfo(sessionId: string): Promise<Session | null>;
|
|
@@ -815,6 +848,14 @@ export declare interface LixaConfig<TProviders extends Record<string, ProviderCo
|
|
|
815
848
|
* @see {@link SessionHandler}
|
|
816
849
|
*/
|
|
817
850
|
sessionHandler?: SessionHandler;
|
|
851
|
+
/**
|
|
852
|
+
* Optional custom resource handler.
|
|
853
|
+
* Handles storage and management of long-lived third-party resource provider tokens (AuthZ)
|
|
854
|
+
* bound directly to user accounts (User ID or Email), independent of transient session IDs.
|
|
855
|
+
*
|
|
856
|
+
* @see {@link ResourceHandler}
|
|
857
|
+
*/
|
|
858
|
+
resourceHandler?: ResourceHandler;
|
|
818
859
|
/**
|
|
819
860
|
* Enable debug logging.
|
|
820
861
|
* When enabled, outputs structured logs for initialization, auth flow, and errors.
|
|
@@ -945,6 +986,55 @@ export declare interface ProviderMetadata {
|
|
|
945
986
|
};
|
|
946
987
|
}
|
|
947
988
|
|
|
989
|
+
/**
|
|
990
|
+
* Resource handler configuration.
|
|
991
|
+
*
|
|
992
|
+
* @public
|
|
993
|
+
*/
|
|
994
|
+
export declare interface ResourceHandler {
|
|
995
|
+
resourceStorage?: ResourceStorage;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Resource storage operations interface.
|
|
1000
|
+
*
|
|
1001
|
+
* @remarks
|
|
1002
|
+
* Manages long-lived third-party resource provider tokens (AuthZ) bound to a user account
|
|
1003
|
+
* (User ID or Email), independent of short-lived user sessions.
|
|
1004
|
+
*
|
|
1005
|
+
* @public
|
|
1006
|
+
*/
|
|
1007
|
+
export declare interface ResourceStorage {
|
|
1008
|
+
/**
|
|
1009
|
+
* Saves a connected resource token for a user.
|
|
1010
|
+
*
|
|
1011
|
+
* @param userId - Unique user identifier or email
|
|
1012
|
+
* @param provider - Resource provider name (e.g. 'github', 'google')
|
|
1013
|
+
* @param resource - Connected resource details including access & refresh tokens
|
|
1014
|
+
*/
|
|
1015
|
+
saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Retrieves a connected resource token for a user.
|
|
1018
|
+
*
|
|
1019
|
+
* @param userId - Unique user identifier or email
|
|
1020
|
+
* @param provider - Resource provider name
|
|
1021
|
+
*/
|
|
1022
|
+
getResource(userId: string, provider: string): Promise<ConnectedResource | null>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Retrieves all connected resources for a user.
|
|
1025
|
+
*
|
|
1026
|
+
* @param userId - Unique user identifier or email
|
|
1027
|
+
*/
|
|
1028
|
+
getUserResources(userId: string): Promise<Record<string, ConnectedResource>>;
|
|
1029
|
+
/**
|
|
1030
|
+
* Deletes a connected resource token for a user.
|
|
1031
|
+
*
|
|
1032
|
+
* @param userId - Unique user identifier or email
|
|
1033
|
+
* @param provider - Resource provider name
|
|
1034
|
+
*/
|
|
1035
|
+
deleteResource(userId: string, provider: string): Promise<void>;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
948
1038
|
/**
|
|
949
1039
|
* Helper type to create a configuration with only registered providers.
|
|
950
1040
|
* Use this with Lixa.createConfig() for type safety.
|