@vizamodo/aws-sts-core 0.3.13 → 0.3.14
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/dist/federation/login.js +17 -4
- package/dist/runtime/edge-cache.d.ts +14 -0
- package/dist/runtime/edge-cache.js +62 -0
- package/dist/sts/issue.js +9 -3
- package/package.json +1 -1
- package/dist/sts/cache.d.ts +0 -3
- package/dist/sts/cache.js +0 -40
package/dist/federation/login.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
+
import { sha256Hex } from "../crypto/sha256";
|
|
2
|
+
import { getEdgeCache, setEdgeCache } from "../runtime/edge-cache";
|
|
1
3
|
export async function buildFederationLoginUrl(input) {
|
|
2
4
|
const session = {
|
|
3
5
|
sessionId: input.accessKeyId,
|
|
4
6
|
sessionKey: input.secretAccessKey,
|
|
5
7
|
sessionToken: input.sessionToken
|
|
6
8
|
};
|
|
9
|
+
const cacheKey = `aws-signin:${await sha256Hex(input.sessionToken)}`;
|
|
7
10
|
const sessionJson = JSON.stringify(session);
|
|
8
11
|
const encoded = encodeURIComponent(sessionJson);
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
12
|
-
|
|
12
|
+
let SigninToken;
|
|
13
|
+
const cached = await getEdgeCache(cacheKey);
|
|
14
|
+
if (cached) {
|
|
15
|
+
SigninToken = cached.SigninToken;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const tokenResp = await fetch(`https://signin.aws.amazon.com/federation?Action=getSigninToken&Session=${encoded}`);
|
|
19
|
+
const json = await tokenResp.json();
|
|
20
|
+
SigninToken = json.SigninToken;
|
|
21
|
+
if (!SigninToken)
|
|
22
|
+
throw new Error("federation_failed");
|
|
23
|
+
// cache SigninToken (AWS token ~15 min → cache 10 min)
|
|
24
|
+
await setEdgeCache(cacheKey, { SigninToken }, 10 * 60).catch(() => { });
|
|
25
|
+
}
|
|
13
26
|
const baseLogin = `https://signin.aws.amazon.com/federation?Action=login` +
|
|
14
27
|
`&Issuer=viza` +
|
|
15
28
|
`&SigninToken=${SigninToken}`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AwsCredentialResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Generic edge cache GET helper
|
|
4
|
+
*/
|
|
5
|
+
export declare function getEdgeCache<T>(key: string): Promise<T | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Generic edge cache SET helper
|
|
8
|
+
*/
|
|
9
|
+
export declare function setEdgeCache(key: string, value: unknown, ttlSec: number): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* ---- STS credential cache helpers ----
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCachedCredentials(cacheKey: string): Promise<AwsCredentialResult | null>;
|
|
14
|
+
export declare function setCachedCredentials(cacheKey: string, result: AwsCredentialResult): Promise<void>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const CACHE_KEY_PREFIX = "https://edge-cache.internal/";
|
|
2
|
+
const CACHE_TTL_BUFFER_SEC = 5 * 60; // 5 minutes safety buffer
|
|
3
|
+
/**
|
|
4
|
+
* Generic edge cache GET helper
|
|
5
|
+
*/
|
|
6
|
+
export async function getEdgeCache(key) {
|
|
7
|
+
try {
|
|
8
|
+
const cache = caches.default;
|
|
9
|
+
const req = new Request(CACHE_KEY_PREFIX + key);
|
|
10
|
+
const res = await cache.match(req);
|
|
11
|
+
if (!res)
|
|
12
|
+
return null;
|
|
13
|
+
try {
|
|
14
|
+
return (await res.json());
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// corrupted cache entry → ignore
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// cache API failure should not break runtime
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generic edge cache SET helper
|
|
28
|
+
*/
|
|
29
|
+
export async function setEdgeCache(key, value, ttlSec) {
|
|
30
|
+
if (ttlSec <= 0)
|
|
31
|
+
return;
|
|
32
|
+
const cache = caches.default;
|
|
33
|
+
const req = new Request(CACHE_KEY_PREFIX + key);
|
|
34
|
+
const body = JSON.stringify(value);
|
|
35
|
+
const res = new Response(body, {
|
|
36
|
+
headers: {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
"Cache-Control": `max-age=${ttlSec}`,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
await cache.put(req, res);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// cache write failure is non-fatal
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* ---- STS credential cache helpers ----
|
|
50
|
+
*/
|
|
51
|
+
export async function getCachedCredentials(cacheKey) {
|
|
52
|
+
return getEdgeCache(cacheKey);
|
|
53
|
+
}
|
|
54
|
+
export async function setCachedCredentials(cacheKey, result) {
|
|
55
|
+
if (!result.expiration)
|
|
56
|
+
return;
|
|
57
|
+
const expiresAt = Date.parse(result.expiration);
|
|
58
|
+
if (!Number.isFinite(expiresAt))
|
|
59
|
+
return;
|
|
60
|
+
const ttlSec = Math.floor((expiresAt - Date.now()) / 1000) - CACHE_TTL_BUFFER_SEC;
|
|
61
|
+
await setEdgeCache(cacheKey, result, ttlSec);
|
|
62
|
+
}
|
package/dist/sts/issue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getEdgeCache, setEdgeCache } from "../runtime/edge-cache";
|
|
2
2
|
import { canonicalizeHeaders } from "../sigv4/headers";
|
|
3
3
|
import { buildCanonicalRequest } from "../sigv4/canonical";
|
|
4
4
|
import { buildStringToSign } from "../sigv4/string-to-sign";
|
|
@@ -136,7 +136,7 @@ export async function issueAwsCredentials(input) {
|
|
|
136
136
|
}
|
|
137
137
|
// ---- cross-request cache lookup (Cloudflare Cache API) ----
|
|
138
138
|
cacheKey = `${region}|${roleArn}|${profileArn}|${trustAnchorArn}|${certSerialDec}`;
|
|
139
|
-
const externalCached = await
|
|
139
|
+
const externalCached = await getEdgeCache(cacheKey);
|
|
140
140
|
if (externalCached) {
|
|
141
141
|
console.log("[sts-cache] edge-hit", { cacheKey });
|
|
142
142
|
return externalCached;
|
|
@@ -246,7 +246,13 @@ export async function issueAwsCredentials(input) {
|
|
|
246
246
|
expiration: creds.expiration,
|
|
247
247
|
};
|
|
248
248
|
// persist credential in edge cache (best effort)
|
|
249
|
-
|
|
249
|
+
if (result.expiration) {
|
|
250
|
+
const expiresAt = Date.parse(result.expiration);
|
|
251
|
+
if (Number.isFinite(expiresAt)) {
|
|
252
|
+
const ttlSec = Math.floor((expiresAt - Date.now()) / 1000) - (5 * 60);
|
|
253
|
+
setEdgeCache(cacheKey, result, ttlSec).catch(() => { });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
250
256
|
// subtract small clock‑skew safety window (5s)
|
|
251
257
|
const exp = new Date(creds.expiration).getTime() - 5000;
|
|
252
258
|
// update cache expiration after success
|
package/package.json
CHANGED
package/dist/sts/cache.d.ts
DELETED
package/dist/sts/cache.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const CACHE_KEY_PREFIX = "https://sts-cache.internal/";
|
|
2
|
-
const CACHE_TTL_BUFFER_SEC = 5 * 60; // 5 minutes safety buffer
|
|
3
|
-
export async function getCachedCredentials(cacheKey) {
|
|
4
|
-
const cache = caches.default;
|
|
5
|
-
const req = new Request(CACHE_KEY_PREFIX + cacheKey);
|
|
6
|
-
const res = await cache.match(req);
|
|
7
|
-
if (!res)
|
|
8
|
-
return null;
|
|
9
|
-
try {
|
|
10
|
-
return (await res.json());
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
// corrupted cache entry → ignore
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export async function setCachedCredentials(cacheKey, result) {
|
|
18
|
-
if (!result.expiration) {
|
|
19
|
-
// cache is optional; skip caching if expiration missing
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const expiresAt = Date.parse(result.expiration);
|
|
23
|
-
if (!Number.isFinite(expiresAt)) {
|
|
24
|
-
// invalid expiration → skip caching
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
const ttlSec = Math.floor((expiresAt - Date.now()) / 1000) - CACHE_TTL_BUFFER_SEC;
|
|
28
|
-
if (ttlSec <= 0)
|
|
29
|
-
return;
|
|
30
|
-
const cache = caches.default;
|
|
31
|
-
const req = new Request(CACHE_KEY_PREFIX + cacheKey);
|
|
32
|
-
const body = JSON.stringify(result);
|
|
33
|
-
const res = new Response(body, {
|
|
34
|
-
headers: {
|
|
35
|
-
"Content-Type": "application/json",
|
|
36
|
-
"Cache-Control": `max-age=${ttlSec}`,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
await cache.put(req, res);
|
|
40
|
-
}
|