@rimelight/security 0.0.19 → 0.0.21
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/config/index.d.mts +1 -1
- package/dist/csp.d.mts +1 -1
- package/dist/csp.mjs +14 -9
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +3 -1
- package/dist/integration.d.mts +26 -0
- package/dist/integration.mjs +20 -0
- package/dist/middleware/construction.d.mts +1 -1
- package/dist/middleware/ratelimit.d.mts +2 -2
- package/dist/middleware/security.d.mts +1 -1
- package/dist/turnstile.d.mts +53 -0
- package/dist/turnstile.mjs +92 -0
- package/dist/{types-Dcvwj-af.d.mts → types-CL5HooHU.d.mts} +5 -0
- package/dist/types.d.mts +1 -1
- package/dist/vite.d.mts +1 -1
- package/package.json +16 -3
- package/src/components/ConstructionPage.astro +166 -0
- package/src/components/ConstructionSignIn.astro +9 -9
- package/src/components/Turnstile.astro +94 -0
- package/src/config/index.ts +2 -0
- package/src/csp.ts +106 -0
- package/src/index.ts +6 -0
- package/src/integration.ts +51 -0
- package/src/layouts/ConstructionLayout.astro +50 -0
- package/src/middleware/construction.ts +315 -0
- package/src/middleware/dev-only.ts +16 -0
- package/src/middleware/index.ts +4 -0
- package/src/middleware/ratelimit.ts +120 -0
- package/src/middleware/security.ts +288 -0
- package/src/pages/construction.astro +5 -0
- package/src/turnstile.ts +172 -0
- package/src/types.ts +213 -0
- package/src/virtual.d.ts +16 -0
- package/src/vite.ts +114 -0
package/src/vite.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createHash } from "node:crypto"
|
|
2
|
+
|
|
3
|
+
import type { SecurityOptions } from "./types"
|
|
4
|
+
|
|
5
|
+
export interface RimelightSecurityPlugin {
|
|
6
|
+
name: string
|
|
7
|
+
enforce?: "pre" | "post"
|
|
8
|
+
resolveId?: (id: string) => string | null | undefined
|
|
9
|
+
load?: (id: string) => string | null | undefined
|
|
10
|
+
buildStart?: () => Promise<void> | void
|
|
11
|
+
generateBundle?: (options: any, bundle: Record<string, any>) => Promise<void> | void
|
|
12
|
+
[key: string]: any
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SecurityPluginOptions extends SecurityOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Additional external script/style URLs to fetch and hash for SRI at build time.
|
|
18
|
+
*/
|
|
19
|
+
resources?: string[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DEFAULT_RESOURCES = ["https://betterlytics.io/analytics.js"]
|
|
23
|
+
|
|
24
|
+
function hashContent(buffer: Buffer | ArrayBuffer | Uint8Array | string): string {
|
|
25
|
+
const hash = createHash("sha384")
|
|
26
|
+
.update(buffer as any)
|
|
27
|
+
.digest("base64")
|
|
28
|
+
return `sha384-${hash}`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Pure Vite Security & SRI Plugin. 1. Accepts framework-agnostic security options (domain, imgSrc,
|
|
33
|
+
* etc.) and exposes virtual:rimelight-security-config. 2. Fetches and hashes external 3rd-party
|
|
34
|
+
* scripts/styles at build time. 3. Emits SRI hashes for locally bundled JS/CSS chunks
|
|
35
|
+
* (Nuxt-security style). 4. Exposes virtual:sri-manifest with a unified URL -> hash mapping.
|
|
36
|
+
*/
|
|
37
|
+
export function security(options: SecurityPluginOptions = {}): RimelightSecurityPlugin {
|
|
38
|
+
const sriManifest: Record<string, string> = {}
|
|
39
|
+
const externalUrls = Array.from(new Set([...DEFAULT_RESOURCES, ...(options.resources || [])]))
|
|
40
|
+
|
|
41
|
+
const sriVirtualId = "virtual:sri-manifest"
|
|
42
|
+
const resolvedSriVirtualId = "\0" + sriVirtualId
|
|
43
|
+
|
|
44
|
+
const configVirtualId = "virtual:rimelight-security-config"
|
|
45
|
+
const resolvedConfigVirtualId = "\0" + configVirtualId
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
name: "vite-plugin-rimelight-security",
|
|
49
|
+
enforce: "post",
|
|
50
|
+
|
|
51
|
+
async buildStart() {
|
|
52
|
+
// 1. Fetch & Hash External Resources (3rd-party SRI)
|
|
53
|
+
if (process.env["NODE_ENV"] === "development") return
|
|
54
|
+
|
|
55
|
+
await Promise.all(
|
|
56
|
+
externalUrls.map(async (url) => {
|
|
57
|
+
if (!url.startsWith("https://")) return
|
|
58
|
+
try {
|
|
59
|
+
const parsed = new URL(url)
|
|
60
|
+
if (parsed.hostname.includes("*")) return
|
|
61
|
+
const pathname = parsed.pathname
|
|
62
|
+
if (pathname === "/" || pathname === "" || pathname.endsWith("/")) return
|
|
63
|
+
|
|
64
|
+
const response = await fetch(url)
|
|
65
|
+
if (!response.ok) return
|
|
66
|
+
const buffer = await response.arrayBuffer()
|
|
67
|
+
sriManifest[url] = hashContent(buffer)
|
|
68
|
+
} catch {
|
|
69
|
+
// Silently ignore unreachable external resources during build
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
generateBundle(_outputOptions, bundle) {
|
|
76
|
+
// 2. Hash Emitted Bundle Chunks & Assets (1st-party SRI)
|
|
77
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
78
|
+
if (!fileName.endsWith(".js") && !fileName.endsWith(".css")) continue
|
|
79
|
+
|
|
80
|
+
let content: string | Uint8Array | undefined
|
|
81
|
+
if (chunk.type === "chunk") {
|
|
82
|
+
content = chunk.code
|
|
83
|
+
} else if (chunk.type === "asset") {
|
|
84
|
+
content = chunk.source
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (content) {
|
|
88
|
+
const hash = hashContent(content)
|
|
89
|
+
// Store both absolute leading slash path and relative file name
|
|
90
|
+
sriManifest[`/${fileName.replace(/^\/+/, "")}`] = hash
|
|
91
|
+
sriManifest[fileName] = hash
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
resolveId(id: string) {
|
|
97
|
+
if (id === sriVirtualId) return resolvedSriVirtualId
|
|
98
|
+
if (id === configVirtualId) return resolvedConfigVirtualId
|
|
99
|
+
return null
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
load(id: string) {
|
|
103
|
+
if (id === resolvedSriVirtualId) {
|
|
104
|
+
return `export const manifest = ${JSON.stringify(sriManifest)};`
|
|
105
|
+
}
|
|
106
|
+
if (id === resolvedConfigVirtualId) {
|
|
107
|
+
return `export const config = ${JSON.stringify(options)};`
|
|
108
|
+
}
|
|
109
|
+
return null
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { security as sri }
|