authtara-sdk 1.0.0
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 +420 -0
- package/dist/index.d.mts +450 -0
- package/dist/index.d.ts +450 -0
- package/dist/index.js +372 -0
- package/dist/index.mjs +340 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# authtara-sdk
|
|
2
|
+
|
|
3
|
+
> **SDK Client untuk integrasi dengan DigitalSolution Platform** - SSO Authentication, Billing/Entitlement Check, dan Usage Metering untuk aplikasi external.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/authtara-sdk)
|
|
6
|
+
[](https://github.com/digitalsolution/authtara-sdk/actions)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## ๐ Features
|
|
10
|
+
|
|
11
|
+
- **๐ SSO Authentication** - Offline JWT verification dengan HS256 + App Secret
|
|
12
|
+
- **๐ณ Billing & Entitlement** - Check tenant access rights dan feature availability
|
|
13
|
+
- **๐ Usage Metering** - Track usage untuk usage-based billing
|
|
14
|
+
- **๐ฏ Type-Safe** - Full TypeScript support dengan comprehensive types
|
|
15
|
+
- **โก Modern** - Built dengan ES Modules, CommonJS, dan TypeScript definitions
|
|
16
|
+
- **๐งช Tested** - Comprehensive unit tests dengan 80%+ coverage
|
|
17
|
+
|
|
18
|
+
## ๐ฆ Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Menggunakan Bun (recommended)
|
|
22
|
+
bun add authtara-sdk
|
|
23
|
+
|
|
24
|
+
# Menggunakan npm
|
|
25
|
+
npm install authtara-sdk
|
|
26
|
+
|
|
27
|
+
# Menggunakan yarn
|
|
28
|
+
yarn add authtara-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## ๐ง Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Initialize SDK
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { Authtara } from "authtara-sdk";
|
|
37
|
+
|
|
38
|
+
const ds = new Authtara({
|
|
39
|
+
apiKey: process.env.DS_APP_SECRET!, // Get from Developer Dashboard
|
|
40
|
+
endpoint: "https://api.digitalsolution.com", // Optional, defaults to production
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Verify SSO Token (Offline)
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Di callback endpoint setelah SSO
|
|
48
|
+
const code = searchParams.get("code");
|
|
49
|
+
const result = await ds.auth.exchangeCode(code!);
|
|
50
|
+
|
|
51
|
+
// Simpan token ke session
|
|
52
|
+
session.set("ds_token", result.token);
|
|
53
|
+
|
|
54
|
+
// Verify token (offline, no network call)
|
|
55
|
+
const session = await ds.auth.verifySession(result.token);
|
|
56
|
+
|
|
57
|
+
console.log("User:", session.user);
|
|
58
|
+
console.log("Tenant:", session.tenant);
|
|
59
|
+
console.log("Plan:", session.subscription.plan);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Check Entitlement
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// Basic access check
|
|
66
|
+
const access = await ds.billing.checkEntitlement({
|
|
67
|
+
tenantId: session.tenant!.id,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!access.granted) {
|
|
71
|
+
return redirect("/upgrade", { reason: access.reason });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Feature-specific check
|
|
75
|
+
const canUseAI = await ds.billing.checkEntitlement({
|
|
76
|
+
tenantId: session.tenant!.id,
|
|
77
|
+
featureKey: "ai_generator",
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (!canUseAI.granted) {
|
|
81
|
+
throw new Error("AI feature not available in your plan");
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 4. Record Usage
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Record API call
|
|
89
|
+
await ds.metering.recordUsage({
|
|
90
|
+
tenantId: session.tenant!.id,
|
|
91
|
+
metricSlug: "api_call",
|
|
92
|
+
amount: 1,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Batch recording
|
|
96
|
+
await ds.metering.recordUsage({
|
|
97
|
+
tenantId: session.tenant!.id,
|
|
98
|
+
metricSlug: "message_sent",
|
|
99
|
+
amount: 50,
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## ๐ API Reference
|
|
104
|
+
|
|
105
|
+
### `Authtara` Constructor
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
new Authtara(config: AuthtaraConfig)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Config Options:**
|
|
112
|
+
|
|
113
|
+
| Option | Type | Required | Default | Description |
|
|
114
|
+
| ---------- | -------- | -------- | --------------------------------- | ----------------------------------- |
|
|
115
|
+
| `apiKey` | `string` | โ
Yes | - | App Secret dari Developer Dashboard |
|
|
116
|
+
| `endpoint` | `string` | No | `https://api.digitalsolution.com` | Base URL Platform API |
|
|
117
|
+
| `timeout` | `number` | No | `30000` | Request timeout dalam milliseconds |
|
|
118
|
+
|
|
119
|
+
### Auth Module
|
|
120
|
+
|
|
121
|
+
#### `auth.verifySession(token: string)`
|
|
122
|
+
|
|
123
|
+
Verify JWT token secara offline menggunakan App Secret.
|
|
124
|
+
|
|
125
|
+
**Returns:** `Promise<SessionVerifyResult>`
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
interface SessionVerifyResult {
|
|
129
|
+
isValid: boolean;
|
|
130
|
+
user?: {
|
|
131
|
+
id: string;
|
|
132
|
+
email: string;
|
|
133
|
+
name: string | null;
|
|
134
|
+
};
|
|
135
|
+
tenant?: {
|
|
136
|
+
id: string;
|
|
137
|
+
name: string;
|
|
138
|
+
subdomain: string;
|
|
139
|
+
role: string;
|
|
140
|
+
};
|
|
141
|
+
subscription?: {
|
|
142
|
+
plan: string;
|
|
143
|
+
status: string;
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Throws:**
|
|
149
|
+
|
|
150
|
+
- `InvalidTokenError` - Token invalid atau expired
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
#### `auth.exchangeCode(code: string)`
|
|
155
|
+
|
|
156
|
+
Exchange authorization code untuk JWT token (server-to-server).
|
|
157
|
+
|
|
158
|
+
**Returns:** `Promise<ExchangeResult>`
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
interface ExchangeResult {
|
|
162
|
+
token: string;
|
|
163
|
+
expiresIn: number;
|
|
164
|
+
user: { id: string; email: string; name: string | null };
|
|
165
|
+
tenant: { id: string; name: string; subdomain: string; role: string };
|
|
166
|
+
subscription: { plan: string; status: string };
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Throws:**
|
|
171
|
+
|
|
172
|
+
- `ConfigurationError` - Code tidak disediakan
|
|
173
|
+
- `ApiError` - Network atau API error
|
|
174
|
+
|
|
175
|
+
### Billing Module
|
|
176
|
+
|
|
177
|
+
#### `billing.checkEntitlement(params: CheckEntitlementParams)`
|
|
178
|
+
|
|
179
|
+
Check apakah tenant memiliki akses ke aplikasi atau fitur spesifik.
|
|
180
|
+
|
|
181
|
+
**Params:**
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
interface CheckEntitlementParams {
|
|
185
|
+
tenantId: string; // Required
|
|
186
|
+
featureKey?: string; // Optional: untuk cek fitur spesifik
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Returns:** `Promise<EntitlementResult>`
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface EntitlementResult {
|
|
194
|
+
granted: boolean;
|
|
195
|
+
reason?: string;
|
|
196
|
+
entitlement?: {
|
|
197
|
+
status: string;
|
|
198
|
+
subscription?: {
|
|
199
|
+
plan: string;
|
|
200
|
+
status: string;
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Metering Module
|
|
207
|
+
|
|
208
|
+
#### `metering.recordUsage(params: RecordUsageParams)`
|
|
209
|
+
|
|
210
|
+
Catat penggunaan untuk usage-based billing.
|
|
211
|
+
|
|
212
|
+
**Params:**
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
interface RecordUsageParams {
|
|
216
|
+
tenantId: string;
|
|
217
|
+
metricSlug: string; // e.g., 'api_call', 'message_sent'
|
|
218
|
+
amount: number; // Harus positif
|
|
219
|
+
timestamp?: string; // Optional ISO timestamp
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Available Metrics:**
|
|
224
|
+
|
|
225
|
+
- `message_sent` - Pesan yang dikirim (agregasi bulanan)
|
|
226
|
+
- `api_call` - API calls (agregasi harian)
|
|
227
|
+
- `connection_active` - Koneksi aktif (agregasi harian)
|
|
228
|
+
- `websocket_connection` - WebSocket connections (agregasi harian)
|
|
229
|
+
|
|
230
|
+
**Returns:** `Promise<RecordUsageResult>`
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
interface RecordUsageResult {
|
|
234
|
+
success: boolean;
|
|
235
|
+
recordId?: string;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## ๐ Error Handling
|
|
240
|
+
|
|
241
|
+
SDK menyediakan custom error classes untuk memudahkan error handling:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import { AuthtaraError, InvalidTokenError, EntitlementDeniedError, ApiError, ConfigurationError } from "authtara-sdk";
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
const session = await ds.auth.verifySession(token);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (error instanceof InvalidTokenError) {
|
|
250
|
+
// Token invalid atau expired - redirect ke login
|
|
251
|
+
return redirect("/login");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (error instanceof ApiError) {
|
|
255
|
+
console.error("API Error:", error.statusCode, error.message);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (error instanceof ConfigurationError) {
|
|
259
|
+
console.error("Configuration Error:", error.message);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Error Hierarchy:**
|
|
265
|
+
|
|
266
|
+
- `AuthtaraError` (base class)
|
|
267
|
+
- `InvalidTokenError` - Token validation errors
|
|
268
|
+
- `EntitlementDeniedError` - Access denied errors
|
|
269
|
+
- `ApiError` - API communication errors
|
|
270
|
+
- `ConfigurationError` - SDK misconfiguration
|
|
271
|
+
|
|
272
|
+
## ๐ ๏ธ Advanced Usage
|
|
273
|
+
|
|
274
|
+
### Custom Timeout
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
const ds = new Authtara({
|
|
278
|
+
apiKey: process.env.DS_APP_SECRET!,
|
|
279
|
+
timeout: 10000, // 10 seconds
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Environment Variables
|
|
284
|
+
|
|
285
|
+
Recommended `.env` setup:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
DS_APP_SECRET=your_app_secret_here
|
|
289
|
+
DS_API_URL=https://api.digitalsolution.com
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### TypeScript Configuration
|
|
293
|
+
|
|
294
|
+
SDK mendukung TypeScript dengan strict mode. Pastikan `tsconfig.json` Anda memiliki:
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"compilerOptions": {
|
|
299
|
+
"moduleResolution": "bundler",
|
|
300
|
+
"esModuleInterop": true
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## ๐งช Testing
|
|
306
|
+
|
|
307
|
+
Untuk testing aplikasi Anda dengan SDK:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { vi } from "vitest";
|
|
311
|
+
|
|
312
|
+
// Mock Authtara SDK
|
|
313
|
+
vi.mock("authtara-sdk", () => ({
|
|
314
|
+
Authtara: vi.fn().mockImplementation(() => ({
|
|
315
|
+
auth: {
|
|
316
|
+
verifySession: vi.fn().mockResolvedValue({
|
|
317
|
+
isValid: true,
|
|
318
|
+
user: { id: "1", email: "test@example.com", name: "Test" },
|
|
319
|
+
tenant: { id: "1", name: "Test Tenant", subdomain: "test", role: "OWNER" },
|
|
320
|
+
}),
|
|
321
|
+
},
|
|
322
|
+
})),
|
|
323
|
+
}));
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## ๐ Integration Examples
|
|
327
|
+
|
|
328
|
+
### Next.js App Router
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// app/api/sso/callback/route.ts
|
|
332
|
+
import { Authtara } from "authtara-sdk";
|
|
333
|
+
|
|
334
|
+
const ds = new Authtara({
|
|
335
|
+
apiKey: process.env.DS_APP_SECRET!,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
export async function GET(request: Request) {
|
|
339
|
+
const { searchParams } = new URL(request.url);
|
|
340
|
+
const code = searchParams.get("code");
|
|
341
|
+
|
|
342
|
+
if (!code) {
|
|
343
|
+
return Response.json({ error: "Missing code" }, { status: 400 });
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const result = await ds.auth.exchangeCode(code);
|
|
347
|
+
|
|
348
|
+
// Set session cookie
|
|
349
|
+
// ... your session logic
|
|
350
|
+
|
|
351
|
+
return Response.redirect("/dashboard");
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Express.js
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import express from "express";
|
|
359
|
+
import { Authtara } from "authtara-sdk";
|
|
360
|
+
|
|
361
|
+
const app = express();
|
|
362
|
+
const ds = new Authtara({
|
|
363
|
+
apiKey: process.env.DS_APP_SECRET!,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
app.get("/api/sso/callback", async (req, res) => {
|
|
367
|
+
const { code } = req.query;
|
|
368
|
+
const result = await ds.auth.exchangeCode(code as string);
|
|
369
|
+
|
|
370
|
+
req.session.token = result.token;
|
|
371
|
+
res.redirect("/dashboard");
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
app.use(async (req, res, next) => {
|
|
375
|
+
if (!req.session.token) return next();
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
const session = await ds.auth.verifySession(req.session.token);
|
|
379
|
+
req.user = session.user;
|
|
380
|
+
req.tenant = session.tenant;
|
|
381
|
+
next();
|
|
382
|
+
} catch (error) {
|
|
383
|
+
req.session.destroy();
|
|
384
|
+
res.redirect("/login");
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## ๐ Migration Guide
|
|
390
|
+
|
|
391
|
+
### From v0.x to v1.x
|
|
392
|
+
|
|
393
|
+
Tidak ada breaking changes - v1.0.0 adalah initial stable release.
|
|
394
|
+
|
|
395
|
+
## ๐ Changelog
|
|
396
|
+
|
|
397
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
398
|
+
|
|
399
|
+
## ๐ค Contributing
|
|
400
|
+
|
|
401
|
+
SDK ini di-maintain oleh DigitalSolution Team. Untuk bug reports atau feature requests:
|
|
402
|
+
|
|
403
|
+
1. Check existing [GitHub Issues](https://github.com/digitalsolution/authtara-sdk/issues)
|
|
404
|
+
2. Create new issue dengan detail yang lengkap
|
|
405
|
+
3. Atau hubungi support di support@digitalsolution.com
|
|
406
|
+
|
|
407
|
+
## ๐ License
|
|
408
|
+
|
|
409
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
410
|
+
|
|
411
|
+
## ๐ Links
|
|
412
|
+
|
|
413
|
+
- **NPM Package:** https://www.npmjs.com/package/authtara-sdk
|
|
414
|
+
- **GitHub Repository:** https://github.com/digitalsolution/authtara-sdk
|
|
415
|
+
- **Documentation:** https://docs.digitalsolution.com/sdk
|
|
416
|
+
- **Developer Dashboard:** https://digitalsolution.com/dashboard/developer
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
**Built with โค๏ธ by DigitalSolution Team**
|