@tertaut/sdk 0.1.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 +126 -0
- package/dist/ai.d.ts +29 -0
- package/dist/ai.js +89 -0
- package/dist/chrome.d.ts +22 -0
- package/dist/chrome.js +70 -0
- package/dist/client.d.ts +124 -0
- package/dist/client.js +124 -0
- package/dist/desktop.d.ts +25 -0
- package/dist/desktop.js +57 -0
- package/dist/guard.d.ts +58 -0
- package/dist/guard.js +255 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8 -0
- package/dist/jwt.d.ts +7 -0
- package/dist/jwt.js +61 -0
- package/dist/storage.d.ts +23 -0
- package/dist/storage.js +189 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.js +1 -0
- package/dist/webhooks.d.ts +24 -0
- package/dist/webhooks.js +43 -0
- package/package.json +54 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
export type AppType = 'WEB_APP' | 'CHROME_EXTENSION' | 'DESKTOP' | 'ANDROID_APK' | 'CLI';
|
|
2
|
+
export type ActivationType = 'MACHINE_BIND' | 'DOMAIN' | 'CHROME_IDENTITY' | 'DEEP_LINK';
|
|
3
|
+
export interface SdkOptions {
|
|
4
|
+
/** Base URL Tertaut (opsional, default: "https://tertaut.com" atau process.env.TERTAUT_API_URL). */
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
/** Kunci lisensi pembeli (opsional jika sudah diaktivasi dan disimpan di storage). */
|
|
7
|
+
licenseKey?: string;
|
|
8
|
+
/** Access token JWT sesi (auth via Authorization: Bearer). */
|
|
9
|
+
accessToken?: string;
|
|
10
|
+
/** Default product slug untuk proteksi dan validasi. */
|
|
11
|
+
productSlug?: string;
|
|
12
|
+
/** Default product ID untuk proxy AI shield. */
|
|
13
|
+
productId?: string;
|
|
14
|
+
/** Toleransi offline token (default: 3 hari / 259,200,000 ms). */
|
|
15
|
+
offlineGracePeriodMs?: number;
|
|
16
|
+
/** Custom storage adapter (default: universal automatic storage). */
|
|
17
|
+
storage?: import('./storage.js').LicenseStorage;
|
|
18
|
+
}
|
|
19
|
+
export interface JwkRsa {
|
|
20
|
+
kty: 'RSA';
|
|
21
|
+
kid: string;
|
|
22
|
+
use?: string;
|
|
23
|
+
alg?: string;
|
|
24
|
+
n: string;
|
|
25
|
+
e: string;
|
|
26
|
+
}
|
|
27
|
+
export interface JwksResponse {
|
|
28
|
+
keys: JwkRsa[];
|
|
29
|
+
}
|
|
30
|
+
/** Hasil normalisasi API dari activationPayload backend. */
|
|
31
|
+
export interface ActivationResult {
|
|
32
|
+
valid: boolean;
|
|
33
|
+
status: string;
|
|
34
|
+
key: string;
|
|
35
|
+
appType: string;
|
|
36
|
+
productName: string;
|
|
37
|
+
productSlug: string;
|
|
38
|
+
durationDays: number | null;
|
|
39
|
+
maxDevices: number;
|
|
40
|
+
devicesUsed: number;
|
|
41
|
+
devices: unknown[];
|
|
42
|
+
expiresAt: string | null;
|
|
43
|
+
offlineToken?: string | null;
|
|
44
|
+
}
|
|
45
|
+
export interface ValidationResult {
|
|
46
|
+
valid: boolean;
|
|
47
|
+
status: string;
|
|
48
|
+
key?: string | null;
|
|
49
|
+
expiresAt?: string | null;
|
|
50
|
+
appType?: string;
|
|
51
|
+
productName?: string;
|
|
52
|
+
productSlug?: string;
|
|
53
|
+
isOfflineGraceValid?: boolean;
|
|
54
|
+
claims?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
export interface OfflineVerifyResult {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
status: 'ACTIVE' | 'EXPIRED';
|
|
59
|
+
claims: Record<string, unknown>;
|
|
60
|
+
expiresAt: string | null;
|
|
61
|
+
}
|
|
62
|
+
export interface UsageResult {
|
|
63
|
+
tokensUsed: number;
|
|
64
|
+
requestCount: number;
|
|
65
|
+
quota: number | null;
|
|
66
|
+
blocked: boolean;
|
|
67
|
+
periodStart: string | null;
|
|
68
|
+
}
|
|
69
|
+
/** Status komprehensif hasil pengecekan lisensi via `tertaut.guard()`. */
|
|
70
|
+
export interface LicenseCheckResult {
|
|
71
|
+
/** True jika lisensi aktif dan sah (baik via server online maupun verifikasi offline RS256). */
|
|
72
|
+
valid: boolean;
|
|
73
|
+
/** Status lisensi: ACTIVE, EXPIRED, NOT_ACTIVATED, OFFLINE_GRACE, SUSPENDED, INVALID */
|
|
74
|
+
status: 'ACTIVE' | 'EXPIRED' | 'NOT_ACTIVATED' | 'OFFLINE_GRACE' | 'SUSPENDED' | 'INVALID';
|
|
75
|
+
/** Kunci lisensi yang digunakan. */
|
|
76
|
+
key?: string;
|
|
77
|
+
/** Nama software / produk. */
|
|
78
|
+
productName?: string;
|
|
79
|
+
/** Slug software. */
|
|
80
|
+
productSlug?: string;
|
|
81
|
+
/** Tanggal masa kedaluwarsa lisensi (ISO string), atau null bila Lifetime. */
|
|
82
|
+
expiresAt?: string | null;
|
|
83
|
+
/** True jika validasi dilakukan tanpa internet berbasis RS256 token offline. */
|
|
84
|
+
offline: boolean;
|
|
85
|
+
/** Alasan jika lisensi tidak valid / kedaluwarsa. */
|
|
86
|
+
reason?: string;
|
|
87
|
+
/** Perangkat yang sedang terdaftar. */
|
|
88
|
+
devicesUsed?: number;
|
|
89
|
+
/** Batas maksimal perangkat. */
|
|
90
|
+
maxDevices?: number;
|
|
91
|
+
/** Data klaim payload lisensi (fitur, tiers, metadata). */
|
|
92
|
+
claims?: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
export interface ProtectOptions {
|
|
95
|
+
/** Kunci lisensi (opsional, jika tidak diberikan akan dibaca dari cache storage). */
|
|
96
|
+
key?: string;
|
|
97
|
+
/** Slug produk Tertaut. */
|
|
98
|
+
productSlug?: string;
|
|
99
|
+
/** Paksa validasi ke server online (abaikan cache offline sesaat). */
|
|
100
|
+
forceRemote?: boolean;
|
|
101
|
+
/** Callback opsional jika lisensi ternyata tidak valid. */
|
|
102
|
+
onInvalid?: (result: LicenseCheckResult) => void | Promise<void>;
|
|
103
|
+
}
|
|
104
|
+
export interface AiMessage {
|
|
105
|
+
role: 'system' | 'user' | 'assistant' | string;
|
|
106
|
+
content: string;
|
|
107
|
+
}
|
|
108
|
+
export interface AiChatOptions {
|
|
109
|
+
/** Nama model AI (misal: 'gpt-4o-mini', 'claude-3-5-sonnet-20241022', 'gemini-1.5-flash'). */
|
|
110
|
+
model: string;
|
|
111
|
+
/** Riwayat pesan chat. */
|
|
112
|
+
messages: AiMessage[];
|
|
113
|
+
/** ID produk di Tertaut (opsional jika sudah diset di createClient). */
|
|
114
|
+
productId?: string;
|
|
115
|
+
/** Provider AI (opsional: OPENAI, ANTHROPIC, OPENROUTER, GEMINI). */
|
|
116
|
+
provider?: string;
|
|
117
|
+
/** Mode streaming response. */
|
|
118
|
+
stream?: boolean;
|
|
119
|
+
/** Nilai temperature (kreativitas model). */
|
|
120
|
+
temperature?: number;
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
}
|
|
123
|
+
export interface AiChatResponse {
|
|
124
|
+
/** Teks balasan dari AI langsung (string). */
|
|
125
|
+
text: string;
|
|
126
|
+
/** Raw JSON payload dari response proxy. */
|
|
127
|
+
raw: any;
|
|
128
|
+
/** Model yang digunakan. */
|
|
129
|
+
model?: string;
|
|
130
|
+
/** Token usage (jika dikembalikan oleh model). */
|
|
131
|
+
usage?: {
|
|
132
|
+
promptTokens?: number;
|
|
133
|
+
completionTokens?: number;
|
|
134
|
+
totalTokens?: number;
|
|
135
|
+
};
|
|
136
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper verifikasi webhook untuk Tertaut MDaaS.
|
|
3
|
+
* Mendukung Node.js, Bun, Edge Runtime, Cloudflare Workers, dan Next.js API Routes.
|
|
4
|
+
*/
|
|
5
|
+
export interface WebhookVerifyOptions {
|
|
6
|
+
/** Raw body string (sebelum di-JSON.parse). */
|
|
7
|
+
rawBody: string;
|
|
8
|
+
/** Nilai dari header 'x-tertaut-signature'. */
|
|
9
|
+
signature: string;
|
|
10
|
+
/** Webhook secret yang disetting di dashboard Tertaut. */
|
|
11
|
+
secret: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const webhooks: {
|
|
14
|
+
/**
|
|
15
|
+
* Verifikasi signature webhook dari Tertaut.
|
|
16
|
+
* @example
|
|
17
|
+
* const isValid = await tertaut.webhooks.verify({
|
|
18
|
+
* rawBody: req.body,
|
|
19
|
+
* signature: req.headers['x-tertaut-signature'],
|
|
20
|
+
* secret: process.env.TERTAUT_WEBHOOK_SECRET
|
|
21
|
+
* })
|
|
22
|
+
*/
|
|
23
|
+
verify(opts: WebhookVerifyOptions): Promise<boolean>;
|
|
24
|
+
};
|
package/dist/webhooks.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper verifikasi webhook untuk Tertaut MDaaS.
|
|
3
|
+
* Mendukung Node.js, Bun, Edge Runtime, Cloudflare Workers, dan Next.js API Routes.
|
|
4
|
+
*/
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
async function hmacSha256Hex(secret, data) {
|
|
7
|
+
const subtle = globalThis.crypto?.subtle;
|
|
8
|
+
if (!subtle) {
|
|
9
|
+
// Fallback Node crypto
|
|
10
|
+
const nodeCrypto = await import('node:crypto').catch(() => null);
|
|
11
|
+
if (nodeCrypto) {
|
|
12
|
+
return nodeCrypto.createHmac('sha256', secret).update(data).digest('hex');
|
|
13
|
+
}
|
|
14
|
+
throw new Error('WebCrypto atau node:crypto diperlukan untuk memverifikasi webhook');
|
|
15
|
+
}
|
|
16
|
+
const key = await subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
17
|
+
const signatureBytes = await subtle.sign('HMAC', key, encoder.encode(data));
|
|
18
|
+
return Array.from(new Uint8Array(signatureBytes))
|
|
19
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
20
|
+
.join('');
|
|
21
|
+
}
|
|
22
|
+
export const webhooks = {
|
|
23
|
+
/**
|
|
24
|
+
* Verifikasi signature webhook dari Tertaut.
|
|
25
|
+
* @example
|
|
26
|
+
* const isValid = await tertaut.webhooks.verify({
|
|
27
|
+
* rawBody: req.body,
|
|
28
|
+
* signature: req.headers['x-tertaut-signature'],
|
|
29
|
+
* secret: process.env.TERTAUT_WEBHOOK_SECRET
|
|
30
|
+
* })
|
|
31
|
+
*/
|
|
32
|
+
async verify(opts) {
|
|
33
|
+
if (!opts.rawBody || !opts.signature || !opts.secret)
|
|
34
|
+
return false;
|
|
35
|
+
try {
|
|
36
|
+
const computed = await hmacSha256Hex(opts.secret, opts.rawBody);
|
|
37
|
+
return computed.toLowerCase() === opts.signature.trim().toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tertaut/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tertaut MDaaS SDK — Universal Licensing Engine (Web/Chrome/Desktop/Android), AI API Proxy Shield client, dan helper verifikasi offline (RS256).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc -p tsconfig.json",
|
|
10
|
+
"prepublishOnly": "npm run build"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./chrome": {
|
|
18
|
+
"types": "./dist/chrome.d.ts",
|
|
19
|
+
"import": "./dist/chrome.js"
|
|
20
|
+
},
|
|
21
|
+
"./desktop": {
|
|
22
|
+
"types": "./dist/desktop.d.ts",
|
|
23
|
+
"import": "./dist/desktop.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"tertaut",
|
|
35
|
+
"mdaas",
|
|
36
|
+
"licensing",
|
|
37
|
+
"software-license",
|
|
38
|
+
"machine-binding",
|
|
39
|
+
"ai-proxy",
|
|
40
|
+
"token-metering",
|
|
41
|
+
"webhooks"
|
|
42
|
+
],
|
|
43
|
+
"author": "PT Retas Lintas Batas <dev@tertaut.com>",
|
|
44
|
+
"homepage": "https://tertaut.com",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/crediblemark-official/tertaut.git",
|
|
48
|
+
"directory": "packages/sdk"
|
|
49
|
+
},
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18"
|
|
53
|
+
}
|
|
54
|
+
}
|