@gjermundgaraba/clankerauth-dev 0.6.0 → 0.7.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 +26 -3
- package/dist/THIRD_PARTY_NOTICES.txt +1 -1
- package/dist/edge.d.ts +16 -8
- package/dist/edge.mjs +2 -2
- package/dist/generate_key_pair-ExJspZNk.mjs +1 -0
- package/dist/index.mjs +39 -39
- package/dist/testing.d.ts +40 -0
- package/dist/testing.mjs +1 -0
- package/dist/web/assets/{index-TYt-q9U4.js → index-DiIqhoq9.js} +17 -17
- package/dist/web/index.html +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Claims set on a signed token. Each one overrides this issuer's default. */
|
|
2
|
+
export interface TokenClaims {
|
|
3
|
+
readonly iss?: string;
|
|
4
|
+
readonly sub?: string;
|
|
5
|
+
readonly aud?: string | Array<string>;
|
|
6
|
+
readonly iat?: number;
|
|
7
|
+
/** Epoch seconds. Default: five minutes from now. */
|
|
8
|
+
readonly exp?: number;
|
|
9
|
+
/** Space-separated, as the wire carries it. */
|
|
10
|
+
readonly scope?: string;
|
|
11
|
+
readonly client_id?: string;
|
|
12
|
+
/** Proof of possession, for checking that a sender-constrained token is refused. */
|
|
13
|
+
readonly cnf?: {
|
|
14
|
+
readonly jkt: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface FakeIssuerOptions {
|
|
18
|
+
/** The resource identifier tokens are minted for: an application's public origin root. */
|
|
19
|
+
readonly resource: string;
|
|
20
|
+
/** The scopes a signed token carries unless the caller names its own. */
|
|
21
|
+
readonly scopes: readonly string[];
|
|
22
|
+
/** Who every credential belongs to. Default `"owner"`. */
|
|
23
|
+
readonly subject?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface FakeIssuer {
|
|
26
|
+
/** What a resource server is configured with: `http://127.0.0.1:<port>/api/auth`. */
|
|
27
|
+
readonly issuer: string;
|
|
28
|
+
/** Sign an access token this issuer's JWKS verifies. */
|
|
29
|
+
readonly sign: (claims?: TokenClaims, typ?: string) => Promise<string>;
|
|
30
|
+
/** Mint an API key the verification endpoint accepts, granted on one resource. */
|
|
31
|
+
readonly apiKey: (scopes: readonly string[], resource?: string) => string;
|
|
32
|
+
/** Stop accepting a minted key, so the next verification answers `401`. */
|
|
33
|
+
readonly revoke: (key: string) => void;
|
|
34
|
+
/** Answer both endpoints with this status instead of serving them; omit to restore. */
|
|
35
|
+
readonly fail: (status?: number) => void;
|
|
36
|
+
/** API-key verifications served, so a test can see that revocation is checked online. */
|
|
37
|
+
readonly verifications: () => number;
|
|
38
|
+
readonly close: () => Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare const startFakeIssuer: (options: FakeIssuerOptions) => Promise<FakeIssuer>;
|
package/dist/testing.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,t as n}from"./generate_key_pair-ExJspZNk.mjs";import{randomBytes as r}from"node:crypto";import{createServer as i}from"node:http";const a=e=>typeof e==`string`,o=e=>{try{let t=JSON.parse(e);if(!(t instanceof Object)||!(`resource`in t))return;let n=t.resource;return a(n)?n:void 0}catch{return}},s=async a=>{let s=a.subject??`owner`,c=await n(`EdDSA`),l={...await t(c.publicKey),kid:`fixture`,alg:`EdDSA`,use:`sig`},u=/* @__PURE__ */ new Map,d=0,f,p=i(async(e,t)=>{let n=(e,n)=>{t.writeHead(e,{"content-type":`application/json`}),t.end(n)};if(e.url===`/api/auth/jwks`)return n(f??200,JSON.stringify({keys:[l]}));if(e.url!==`/api/issuer/verifyApiKey`||e.method!==`POST`)return n(404,`{}`);if(d++,f!==void 0)return n(f,`{}`);let r=u.get(e.headers.authorization?.replace(/^Bearer /iu,``)??``);if(r===void 0)return n(401,`{"error":"Invalid API key"}`);let i=``;for await(let t of e)i+=String(t);let a=o(i);return a===void 0?n(400,`{"error":"Invalid request"}`):a===r.resource?n(200,JSON.stringify({keyId:r.keyId,ownerId:s,resource:r.resource,scopes:r.scopes,expiresAt:null})):n(403,`{"error":"No access to this Resource"}`)});await new Promise(e=>p.listen(0,`127.0.0.1`,e));let m=p.address();if(!(m instanceof Object))throw Error(`The fake issuer failed to bind a TCP port`);let h=`http://127.0.0.1:${m.port}/api/auth`;return{issuer:h,sign:(t={},n=`at+jwt`)=>{let r=Math.floor(Date.now()/1e3);return new e({iss:h,sub:s,aud:a.resource,iat:r,exp:r+300,client_id:`fixture`,scope:a.scopes.join(` `),...t}).setProtectedHeader({alg:`EdDSA`,kid:`fixture`,typ:n}).sign(c.privateKey)},apiKey:(e,t=a.resource)=>{let n=`ca_${r(24).toString(`base64url`)}`;return u.set(n,{keyId:`key-${u.size+1}`,resource:t,scopes:e}),n},revoke:e=>{u.delete(e)},fail:e=>{f=e},verifications:()=>d,close:()=>new Promise((e,t)=>{p.closeAllConnections(),p.close(n=>n?t(n):e())})}};export{s as startFakeIssuer};
|