@kawanua/license-sdk 1.0.1 → 1.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 +1 -1
- package/index.js +16 -44
- package/package.json +1 -1
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -29,22 +29,10 @@
|
|
|
29
29
|
|
|
30
30
|
// ─── Konstanta ──────────────────────────────────────────────────
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*/
|
|
37
|
-
const KAWANUA_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
38
|
-
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2a2rwplBQLzHPZe5TNJF
|
|
39
|
-
... (ganti dengan public key RS256 aktual dari server kamu) ...
|
|
40
|
-
-----END PUBLIC KEY-----`;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* URL endpoint JWKS publik — alternatif lebih dinamis dari hardcode PEM.
|
|
44
|
-
* SDK akan fetch public key dari sini jika PEM tidak di-set.
|
|
45
|
-
* Endpoint ini harus tersedia di server Kawanua.
|
|
46
|
-
*/
|
|
47
|
-
const JWKS_URL = "https://lisensi.kawanua.workers.dev/.well-known/jwks.json";
|
|
32
|
+
// Public key RS256 dari server lisensi Kawanua (Base64-encoded PEM).
|
|
33
|
+
// Klien hanya bisa VERIFY — tidak bisa forge token baru.
|
|
34
|
+
const KAWANUA_PUBLIC_KEY_B64 =
|
|
35
|
+
"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEzTFgrbDdKbS9VQ25nZ1VmcVhXMAoxazN2M2FYR0RRdEF3Z2NyeVFad1lUY2x5SzdQdFdxMG10ejArUDRyTW0veFBhdmlaQlRaYUt4aVdScWVTQUhUCk4wVDdVSFRSbnJjaElwY1JaeExiTXlzWHJ6eS9NcjZ3cTF1aW5FUjJ1TGNjRE9Hc2swR0Q4QU1TWU54Q1NsZ24KcFREN200R0g0TE1DTzNPU2dXYm9Ua0VWdkp2TXN5ckZ2TTlTT2N1UG9NTmJyTGk2SDVnOTR2OU9UWkRvTzhZeQo0RXUwQjRaM3luVS9iRzY2TFZmWGNTYlNBaGU4TWZ6NDZ2UUxzMXJJNUpqZElhajAxWDdsamw1cWdWcklCRHhkCjhneXUxK1FZcXZjYTdzaTRUVkZzOTlYV0xlUVpBWWh2UC9kT3gvdWxvNE1CL1doQU9NRWNwai9kaGVHYk5ieTcKZ3dJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="; // <- isi dengan base64(PUBLIC_KEY_PEM)
|
|
48
36
|
|
|
49
37
|
/** Feature map per plan — single source of truth */
|
|
50
38
|
const PLAN_FEATURES = {
|
|
@@ -112,15 +100,17 @@ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2a2rwplBQLzHPZe5TNJF
|
|
|
112
100
|
}
|
|
113
101
|
|
|
114
102
|
/**
|
|
115
|
-
* Import public key RS256 dari PEM
|
|
116
|
-
* Menggunakan Web Crypto API (tersedia di semua browser modern).
|
|
103
|
+
* Import public key RS256 dari base64-encoded PEM ke CryptoKey.
|
|
117
104
|
*/
|
|
118
|
-
async function _importPublicKey(
|
|
105
|
+
async function _importPublicKey(b64) {
|
|
106
|
+
const pem = atob(b64);
|
|
119
107
|
const pemBody = pem
|
|
120
108
|
.replace(/-----BEGIN PUBLIC KEY-----/, "")
|
|
121
109
|
.replace(/-----END PUBLIC KEY-----/, "")
|
|
122
110
|
.replace(/\s+/g, "");
|
|
111
|
+
|
|
123
112
|
const der = Uint8Array.from(atob(pemBody), (c) => c.charCodeAt(0));
|
|
113
|
+
|
|
124
114
|
return crypto.subtle.importKey(
|
|
125
115
|
"spki",
|
|
126
116
|
der.buffer,
|
|
@@ -130,24 +120,6 @@ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2a2rwplBQLzHPZe5TNJF
|
|
|
130
120
|
);
|
|
131
121
|
}
|
|
132
122
|
|
|
133
|
-
/**
|
|
134
|
-
* Fetch public key dari JWKS endpoint.
|
|
135
|
-
* Fallback jika PEM belum di-hardcode (mode dinamis).
|
|
136
|
-
*/
|
|
137
|
-
async function _fetchPublicKeyFromJWKS(kid) {
|
|
138
|
-
const res = await fetch(JWKS_URL, { cache: "force-cache" });
|
|
139
|
-
const jwks = await res.json();
|
|
140
|
-
const jwk = kid ? jwks.keys.find((k) => k.kid === kid) : jwks.keys[0];
|
|
141
|
-
if (!jwk) throw new Error("No matching key found in JWKS");
|
|
142
|
-
return crypto.subtle.importKey(
|
|
143
|
-
"jwk",
|
|
144
|
-
jwk,
|
|
145
|
-
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
|
|
146
|
-
false,
|
|
147
|
-
["verify"],
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
123
|
/**
|
|
152
124
|
* Verifikasi signature JWT dengan RS256.
|
|
153
125
|
* Returns true jika valid, false jika tidak.
|
|
@@ -197,14 +169,14 @@ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2a2rwplBQLzHPZe5TNJF
|
|
|
197
169
|
);
|
|
198
170
|
}
|
|
199
171
|
|
|
200
|
-
//
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
publicKey = await _fetchPublicKeyFromJWKS(header.kid);
|
|
172
|
+
// Fail-fast jika public key belum dikonfigurasi.
|
|
173
|
+
if (!KAWANUA_PUBLIC_KEY_B64) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
"[KawanuaLicense] KAWANUA_PUBLIC_KEY_B64 belum dikonfigurasi. " +
|
|
176
|
+
"Hubungi Kawanua untuk mendapatkan public key SDK kamu.",
|
|
177
|
+
);
|
|
207
178
|
}
|
|
179
|
+
const publicKey = await _importPublicKey(KAWANUA_PUBLIC_KEY_B64);
|
|
208
180
|
|
|
209
181
|
// Verify signature
|
|
210
182
|
const isValid = await _verifySignature(token, publicKey);
|