Skip to content

Commit

Permalink
feat: support cloudflare access when access remote storage
Browse files Browse the repository at this point in the history
  • Loading branch information
RihanArfan committed Oct 26, 2024
1 parent 50cee14 commit 3096ac3
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 7 deletions.
10 changes: 9 additions & 1 deletion src/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface HubConfig {
userToken?: string
env?: string
version?: string
cloudflareAccess?: {
clientId: string
clientSecret: string
}

ai?: boolean
analytics?: boolean
Expand Down Expand Up @@ -310,7 +314,11 @@ export async function setupRemote(_nuxt: Nuxt, hub: HubConfig) {
const remoteManifest = hub.remoteManifest = await $fetch<HubConfig['remoteManifest']>('/api/_hub/manifest', {
baseURL: hub.projectUrl as string,
headers: {
authorization: `Bearer ${hub.projectSecretKey || hub.userToken}`
authorization: `Bearer ${hub.projectSecretKey || hub.userToken}`,
...(hub.cloudflareAccess?.clientId && hub.cloudflareAccess?.clientSecret && {
'CF-Access-Client-Id': hub.cloudflareAccess?.clientId,
'CF-Access-Client-Secret': hub.cloudflareAccess?.clientSecret
})
}
})
.catch(async (err) => {
Expand Down
5 changes: 5 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export default defineNuxtModule<ModuleOptions>({
hyperdrive: {},
// @ts-expect-error nitro.cloudflare.wrangler is not yet typed
compatibilityFlags: nuxt.options.nitro.cloudflare?.wrangler?.compatibility_flags
},
// Cloudflare Access
cloudflareAccess: {
clientId: process.env.NUXT_HUB_CLOUDFLARE_ACCESS_CLIENT_ID || null,
clientSecret: process.env.NUXT_HUB_CLOUDFLARE_ACCESS_CLIENT_SECRET || null
}
})
runtimeConfig.hub = hub
Expand Down
4 changes: 3 additions & 1 deletion src/runtime/ai/server/utils/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { H3Error } from 'h3'
import type { Ai } from '@cloudflare/workers-types/experimental'
import { requireNuxtHubFeature } from '../../../utils/features'
import { useRuntimeConfig } from '#imports'
import { getCloudflareAccessHeaders } from '~/src/runtime/utils/cloudflareAccess'

let _ai: Ai

Expand All @@ -30,7 +31,8 @@ export function hubAI(): Ai {
// @ts-expect-error globalThis.__env__ is not defined
const binding = process.env.AI || globalThis.__env__?.AI || globalThis.AI
if (hub.remote && hub.projectUrl && !binding) {
_ai = proxyHubAI(hub.projectUrl, hub.projectSecretKey || hub.userToken)
const cfAccessHeaders = getCloudflareAccessHeaders(hub.cloudflareAccess)
_ai = proxyHubAI(hub.projectUrl, hub.projectSecretKey || hub.userToken, cfAccessHeaders)
return _ai
}
if (binding) {
Expand Down
4 changes: 3 additions & 1 deletion src/runtime/analytics/server/utils/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { joinURL } from 'ufo'
import { createError } from 'h3'
import { requireNuxtHubFeature } from '../../../utils/features'
import { useRuntimeConfig } from '#imports'
import { getCloudflareAccessHeaders } from '~/src/runtime/utils/cloudflareAccess'

const _datasets: Record<string, AnalyticsEngineDataset> = {}

Expand Down Expand Up @@ -45,7 +46,8 @@ export function hubAnalytics() {
const hub = useRuntimeConfig().hub
const binding = getAnalyticsBinding()
if (hub.remote && hub.projectUrl && !binding) {
return proxyHubAnalytics(hub.projectUrl, hub.projectSecretKey || hub.userToken)
const cfAccessHeaders = getCloudflareAccessHeaders(hub.cloudflareAccess)
return proxyHubAnalytics(hub.projectUrl, hub.projectSecretKey || hub.userToken, cfAccessHeaders)
}
const dataset = _useDataset()

Expand Down
4 changes: 3 additions & 1 deletion src/runtime/blob/server/utils/blob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { BlobType, FileSizeUnit, BlobUploadedPart, BlobListResult, BlobMult
import { streamToArrayBuffer } from '../../../utils/stream'
import { requireNuxtHubFeature } from '../../../utils/features'
import { useRuntimeConfig } from '#imports'
import { getCloudflareAccessHeaders } from '~/src/runtime/utils/cloudflareAccess'

const _r2_buckets: Record<string, R2Bucket> = {}

Expand Down Expand Up @@ -154,7 +155,8 @@ export function hubBlob(): HubBlob {
const hub = useRuntimeConfig().hub
const binding = getBlobBinding()
if (hub.remote && hub.projectUrl && !binding) {
return proxyHubBlob(hub.projectUrl, hub.projectSecretKey || hub.userToken)
const cfAccessHeaders = getCloudflareAccessHeaders(hub.cloudflareAccess)
return proxyHubBlob(hub.projectUrl, hub.projectSecretKey || hub.userToken, cfAccessHeaders)
}
const bucket = _useBucket()

Expand Down
4 changes: 3 additions & 1 deletion src/runtime/database/server/utils/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { H3Error } from 'h3'
import type { D1Database } from '@nuxthub/core'
import { requireNuxtHubFeature } from '../../../utils/features'
import { useRuntimeConfig } from '#imports'
import { getCloudflareAccessHeaders } from '~/src/runtime/utils/cloudflareAccess'

let _db: D1Database

Expand All @@ -28,7 +29,8 @@ export function hubDatabase(): D1Database {
// @ts-expect-error globalThis.__env__ is not defined
const binding = process.env.DB || globalThis.__env__?.DB || globalThis.DB
if (hub.remote && hub.projectUrl && !binding) {
_db = proxyHubDatabase(hub.projectUrl, hub.projectSecretKey || hub.userToken)
const cfAccessHeaders = getCloudflareAccessHeaders(hub.cloudflareAccess)
_db = proxyHubDatabase(hub.projectUrl, hub.projectSecretKey || hub.userToken, cfAccessHeaders)
return _db
}
if (binding) {
Expand Down
4 changes: 3 additions & 1 deletion src/runtime/kv/server/utils/kv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createError } from 'h3'
import type { HubKV } from '@nuxthub/core'
import { requireNuxtHubFeature } from '../../../utils/features'
import { useRuntimeConfig } from '#imports'
import { getCloudflareAccessHeaders } from '~/src/runtime/utils/cloudflareAccess'

let _kv: HubKV

Expand All @@ -29,7 +30,8 @@ export function hubKV(): HubKV {
// @ts-expect-error globalThis.__env__ is not defined
const binding = process.env.KV || globalThis.__env__?.KV || globalThis.KV
if (hub.remote && hub.projectUrl && !binding) {
return proxyHubKV(hub.projectUrl, hub.projectSecretKey || hub.userToken)
const cfAccessHeaders = getCloudflareAccessHeaders(hub.cloudflareAccess)
return proxyHubKV(hub.projectUrl, hub.projectSecretKey || hub.userToken, cfAccessHeaders)
}
if (binding) {
const storage = createStorage({
Expand Down
10 changes: 10 additions & 0 deletions src/runtime/utils/cloudflareAccess.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { HubConfig } from '~/src/features'

export function getCloudflareAccessHeaders(access: HubConfig['cloudflareAccess']): Record<string, string> {
const isCloudflareAccessEnabled = !!(access?.clientId && access?.clientSecret)
if (!isCloudflareAccessEnabled) return {}
return {
'CF-Access-Client-Id': access?.clientId,
'CF-Access-Client-Secret': access?.clientSecret
}
}
4 changes: 3 additions & 1 deletion src/runtime/vectorize/server/utils/vectorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { RuntimeConfig } from 'nuxt/schema'
import type { Vectorize } from '../../../../types/vectorize'
import { requireNuxtHubFeature } from '../../../utils/features'
import { useRuntimeConfig } from '#imports'
import { getCloudflareAccessHeaders } from '~/src/runtime/utils/cloudflareAccess'

const _vectorize: Record<string, Vectorize> = {}

Expand Down Expand Up @@ -42,7 +43,8 @@ export function hubVectorize(index: VectorizeIndexes): Vectorize {
// @ts-expect-error globalThis.__env__ is not defined
const binding = process.env[bindingName] || globalThis.__env__?.[bindingName] || globalThis[bindingName]
if (hub.remote && hub.projectUrl && !binding) {
_vectorize[index] = proxyHubVectorize(index, hub.projectUrl, hub.projectSecretKey || hub.userToken)
const cfAccessHeaders = getCloudflareAccessHeaders(hub.cloudflareAccess)
_vectorize[index] = proxyHubVectorize(index, hub.projectUrl, hub.projectSecretKey || hub.userToken, cfAccessHeaders)
return _vectorize[index]
}
if (binding) {
Expand Down
16 changes: 16 additions & 0 deletions src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,20 @@ export interface ModuleOptions {
[key: string]: string
}
}
/**
* Cloudflare Access authentication for remote storage.
* @see https://hub.nuxt.com/recipes/cloudflare-access
*/
cloudflareAccess?: {
/**
* The client ID for Cloudflare Access.
* @default process.env.NUXT_HUB_CLOUDFLARE_ACCESS_CLIENT_ID
*/
clientId?: string
/**
* The client secret for Cloudflare Access.
* @default process.env.NUXT_HUB_CLOUDFLARE_ACCESS_CLIENT_SECRET
*/
clientSecret?: string
}
}

0 comments on commit 3096ac3

Please sign in to comment.