Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ jobs:
secrets:
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
APT_PACKAGES: mkcert
DRY_RUN: true
build:
name: Build
Expand All @@ -37,6 +36,8 @@ jobs:
permissions:
packages: write
with:
BUILD_ADD_HOSTS: |
app.localhost=127.0.0.1
BUILD_ARGUMENTS: ${{ (needs.release_semantic_dry.outputs.new_release_version != null) && format('RELEASE_NAME={0}', needs.release_semantic_dry.outputs.new_release_version) || '' }}
TAG: ${{ (needs.release_semantic_dry.outputs.new_release_version != null) && needs.release_semantic_dry.outputs.new_release_version || '' }}
secrets:
Expand All @@ -50,5 +51,3 @@ jobs:
id-token: write
secrets:
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
APT_PACKAGES: mkcert
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ RUN --mount=type=secret,id=SENTRY_AUTH_TOKEN,env=SENTRY_AUTH_TOKEN \

# FROM prepare AS build-static

# ARG NUXT_PUBLIC_SITE_URL=https://localhost:3002
# ENV NUXT_PUBLIC_SITE_URL=${NUXT_PUBLIC_SITE_URL}
# ARG NUXT_PUBLIC_I18N_BASE_URL=https://localhost:3002
# ENV NUXT_PUBLIC_I18N_BASE_URL=${NUXT_PUBLIC_I18N_BASE_URL}

# ENV NODE_ENV=production
# RUN pnpm --dir src run build:static
Expand Down
5 changes: 3 additions & 2 deletions src/config/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ export const modulesConfig: ReturnType<DefineNuxtConfig> = {
fonts: {
families: [
{
formats: ['ttf'],
global: true,
name: 'Raleway',
provider: 'fontsource',
weights: [400, 700],
global: true,
formats: ['ttf'],
},
],
},
Expand Down
4 changes: 2 additions & 2 deletions src/node/static/environment.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export const IS_IN_PRODUCTION = process.env.NODE_ENV === 'production'
export const IS_IN_STACK = !!process.env.NUXT_PUBLIC_SITE_URL
export const IS_IN_STACK = !!process.env.NUXT_PUBLIC_I18N_BASE_URL
export const IS_IN_FRONTEND_DEVELOPMENT = !IS_IN_PRODUCTION && !IS_IN_STACK

export const IS_NITRO_OPENAPI_ENABLED =
!!process.env.NUXT_IS_NITRO_OPENAPI_ENABLED || false
export const NUXT_PUBLIC_VIO_ENVIRONMENT = process.env.NODE_ENV
export const SITE_URL =
process.env.NUXT_PUBLIC_SITE_URL ||
process.env.NUXT_PUBLIC_I18N_BASE_URL ||
`https://${process.env.HOST || 'app.localhost'}:${process.env.PORT || '3000'}`
export const SITE_URL_TYPED = new URL(SITE_URL)
4 changes: 2 additions & 2 deletions src/server/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const GET_CSP = ({
}) => {
const domainTldPort = IS_IN_FRONTEND_DEVELOPMENT
? PRODUCTION_HOST
: siteUrl.host
: getRootHost(siteUrl.host)

return defu(
// if (isHttps(event.node.req)) {
Expand All @@ -22,7 +22,7 @@ export const GET_CSP = ({
// app
'connect-src': [
'blob:', // vue-advanced-cropper
`https://${domainTldPort}`, // `/api` requests
`https://app.${domainTldPort}`, // `/api` requests
`https://postgraphile.${domainTldPort}`, // backend requests
`https://tusd.${domainTldPort}`, // image upload requests
'https://nominatim.openstreetmap.org/search', // map's geocoder
Expand Down
12 changes: 12 additions & 0 deletions src/shared/utils/networking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ export const getHost = (event: H3Event) => {

export { getIsSecure } from '~~/node/static'

export const getRootHost = (host: string) => {
const hostParts = host.split('.')
const hostPartsLast = hostParts[hostParts.length - 1]

if (hostPartsLast && /^localhost(:[0-9]+)?$/.test(hostPartsLast))
return hostPartsLast

if (hostParts.length === 1) return hostParts[0]

return `${hostParts[hostParts.length - 2]}.${hostPartsLast}`
}

export const getServiceHref = ({
host,
isSsr = true,
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/fixtures/appTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ export const appTest = test.extend<{
defaultPage: async ({ page, context }, use) => {
await context.addCookies([
{
domain: 'localhost',
domain: 'app.localhost',
name: TESTING_COOKIE_NAME,
path: '/',
value: 'true',
},
{
domain: 'localhost',
domain: 'app.localhost',
name: TIMEZONE_COOKIE_NAME,
path: '/',
value: TIMEZONE_DEFAULT,
},
{
domain: 'localhost',
domain: 'app.localhost',
name: COOKIE_CONTROL_CONSENT_COOKIE_NAME,
path: '/',
value: COOKIE_CONTROL_CONSENT_COOKIE_DEFAULT_VALUE,
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"@context":"https://schema.org","@graph":[{"@id":"https://localhost:3001/#website","@type":"WebSite","description":"Find events, guests and friends 💙❤️💚","inLanguage":"en","name":"Vibetype","url":"https://localhost:3001/","workTranslation":{"@id":"https://localhost:3001/de#website"}},{"@id":"https://localhost:3001/#webpage","@type":"WebPage","description":"Find events, guests and friends 💙❤️💚","name":"Vibetype","url":"https://localhost:3001/","isPartOf":{"@id":"https://localhost:3001/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://localhost:3001/"]}]}]}
{"@context":"https://schema.org","@graph":[{"@id":"https://app.localhost:3001/#website","@type":"WebSite","description":"Find events, guests and friends 💙❤️💚","inLanguage":"en","name":"Vibetype","url":"https://app.localhost:3001/","workTranslation":{"@id":"https://app.localhost:3001/de#website"}},{"@id":"https://app.localhost:3001/#webpage","@type":"WebPage","description":"Find events, guests and friends 💙❤️💚","name":"Vibetype","url":"https://app.localhost:3001/","isPartOf":{"@id":"https://app.localhost:3001/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://app.localhost:3001/"]}]}]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"@context":"https://schema.org","@graph":[{"@id":"https://localhost:3001/#website","@type":"WebSite","description":"Find events, guests and friends 💙❤️💚","inLanguage":"en","name":"Vibetype","url":"https://localhost:3001/","workTranslation":{"@id":"https://localhost:3001/de#website"}},{"@id":"https://localhost:3001/#webpage","@type":"WebPage","description":"Find events, guests and friends 💙❤️💚","name":"Vibetype","url":"https://localhost:3001/","isPartOf":{"@id":"https://localhost:3001/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://localhost:3001/"]}]}]}
{"@context":"https://schema.org","@graph":[{"@id":"https://app.localhost:3001/#website","@type":"WebSite","description":"Find events, guests and friends 💙❤️💚","inLanguage":"en","name":"Vibetype","url":"https://app.localhost:3001/","workTranslation":{"@id":"https://app.localhost:3001/de#website"}},{"@id":"https://app.localhost:3001/#webpage","@type":"WebPage","description":"Find events, guests and friends 💙❤️💚","name":"Vibetype","url":"https://app.localhost:3001/","isPartOf":{"@id":"https://app.localhost:3001/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://app.localhost:3001/"]}]}]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"@context":"https://schema.org","@graph":[{"@id":"https://localhost:3001/#website","@type":"WebSite","description":"Find events, guests and friends 💙❤️💚","inLanguage":"en","name":"Vibetype","url":"https://localhost:3001/","workTranslation":{"@id":"https://localhost:3001/de#website"}},{"@id":"https://localhost:3001/#webpage","@type":"WebPage","description":"Find events, guests and friends 💙❤️💚","name":"Vibetype","url":"https://localhost:3001/","isPartOf":{"@id":"https://localhost:3001/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://localhost:3001/"]}]}]}
{"@context":"https://schema.org","@graph":[{"@id":"https://app.localhost:3001/#website","@type":"WebSite","description":"Find events, guests and friends 💙❤️💚","inLanguage":"en","name":"Vibetype","url":"https://app.localhost:3001/","workTranslation":{"@id":"https://app.localhost:3001/de#website"}},{"@id":"https://app.localhost:3001/#webpage","@type":"WebPage","description":"Find events, guests and friends 💙❤️💚","name":"Vibetype","url":"https://app.localhost:3001/","isPartOf":{"@id":"https://app.localhost:3001/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://app.localhost:3001/"]}]}]}
2 changes: 1 addition & 1 deletion tests/e2e/specs/server/headers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test.describe('headers middleware', () => {

const HEADERS = {
'access-control-allow-origin': '*',
'Content-Security-Policy': `base-uri 'none'; default-src 'none'; connect-src blob: https://localhost:3001 https://postgraphile.localhost:3001 https://tusd.localhost:3001 https://nominatim.openstreetmap.org/search https://cloudflareinsights.com https://firebaseinstallations.googleapis.com https://fcmregistrations.googleapis.com https://*.analytics.google.com https://*.google-analytics.com https://*.googletagmanager.com https://o4507213726154752.ingest.de.sentry.io/api/4507213736837200/envelope/ 'self'; font-src 'self' data:; form-action 'self'; frame-ancestors 'none'; frame-src https://challenges.cloudflare.com; img-src blob: https://tile.openstreetmap.org/ https://tusd.localhost:3001 https://media3.giphy.com/ https://www.gravatar.com/avatar/ https://*.google-analytics.com https://*.googletagmanager.com 'self' data:; manifest-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'wasm-unsafe-eval'; worker-src https://localhost:3001/sw.js blob:; script-src-elem https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js https://static.cloudflareinsights.com https://localhost:3001/cdn-cgi/ https://challenges.cloudflare.com https://*.googletagmanager.com 'nonce' https://localhost:3001/_nuxt/;`,
'Content-Security-Policy': `base-uri 'none'; default-src 'none'; connect-src blob: https://app.localhost:3001 https://postgraphile.localhost:3001 https://tusd.localhost:3001 https://nominatim.openstreetmap.org/search https://cloudflareinsights.com https://firebaseinstallations.googleapis.com https://fcmregistrations.googleapis.com https://*.analytics.google.com https://*.google-analytics.com https://*.googletagmanager.com https://o4507213726154752.ingest.de.sentry.io/api/4507213736837200/envelope/ 'self'; font-src 'self' data:; form-action 'self'; frame-ancestors 'none'; frame-src https://challenges.cloudflare.com; img-src blob: https://tile.openstreetmap.org/ https://tusd.localhost:3001 https://media3.giphy.com/ https://www.gravatar.com/avatar/ https://*.google-analytics.com https://*.googletagmanager.com 'self' data:; manifest-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'wasm-unsafe-eval'; worker-src https://app.localhost:3001/sw.js blob:; script-src-elem https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js https://static.cloudflareinsights.com https://app.localhost:3001/cdn-cgi/ https://challenges.cloudflare.com https://*.googletagmanager.com 'nonce' https://app.localhost:3001/_nuxt/;`,
'content-type': 'text/html;charset=utf-8',
'Cross-Origin-Embedder-Policy': 'credentialless',
'Cross-Origin-Opener-Policy': 'same-origin',
Expand Down
10 changes: 3 additions & 7 deletions tests/e2e/specs/server/robots.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ testPageLoad(PAGE_PATH)
test.describe('robots.txt', () => {
test('content', async ({ request }) => {
const resp = await request.get(PAGE_PATH)
expect(
(await resp.text()).replace(
new RegExp(SITE_URL, 'g'),
'https://example.com',
),
).toMatchSnapshot(
const text = (await resp.text()).replaceAll(SITE_URL, 'https://example.com')
expect(text).toMatchSnapshot(
`robots-txt-content-${
process.env.NODE_ENV === 'production' ? 'production' : 'development'
process.env.VIO_SERVER === 'development' ? 'development' : 'production'
}.txt`,
)
})
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ export const PAGE_READY = async ({
}
}
export const SITE_URL =
process.env.NUXT_PUBLIC_SITE_URL ||
`https://${process.env.HOST || 'localhost'}:${process.env.PORT || '3000'}`
process.env.NUXT_PUBLIC_I18N_BASE_URL ||
`https://${process.env.HOST || 'app.localhost'}:${process.env.PORT || '3000'}`
56 changes: 17 additions & 39 deletions tests/e2e/utils/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,7 @@ export const testMetadata = async ({
key: 'property',
value: 'og:image',
},
// TODO: check for open graph image content differently
// {
// key: 'content',
// value: joinURL(
// SITE_URL,
// `/__og-image__/${
// process.env.VIO_SERVER === 'static' ? 'static' : 'image'
// }`,
// path,
// '/og.png',
// ),
// },
// content is checked below
],
},
{
Expand Down Expand Up @@ -145,18 +134,7 @@ export const testMetadata = async ({
key: 'name',
value: 'twitter:image',
},
// TODO: check for open graph image content differently
// {
// key: 'content',
// value: joinURL(
// SITE_URL,
// `/__og-image__/${
// process.env.VIO_SERVER === 'static' ? 'static' : 'image'
// }`,
// path,
// '/og.png',
// ),
// },
// content is checked below
],
},
{
Expand All @@ -166,18 +144,7 @@ export const testMetadata = async ({
key: 'name',
value: 'twitter:image:src',
},
// TODO: check for open graph image content differently
// {
// key: 'content',
// value: joinURL(
// SITE_URL,
// `/__og-image__/${
// process.env.VIO_SERVER === 'static' ? 'static' : 'image'
// }`,
// path,
// '/og.png',
// ),
// },
// content is checked below
],
},
{
Expand Down Expand Up @@ -325,9 +292,9 @@ export const testMetadata = async ({
{
key: 'content',
value:
process.env.NODE_ENV === 'production'
? 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1'
: 'noindex, nofollow',
process.env.VIO_SERVER === 'development'
? 'noindex, nofollow'
: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1',
},
],
},
Expand Down Expand Up @@ -531,6 +498,17 @@ export const testMetadata = async ({
// .innerText(),
// ).toMatchSnapshot(`content-security-policy.txt`)
// }

for (const locator of [
'meta[property="og:image"]',
'meta[name="twitter:image"]',
'meta[name="twitter:image:src"]',
]) {
const content = await page.locator(locator).getAttribute('content')
expect(content).toBeTruthy()
expect(content?.startsWith(SITE_URL)).toBeTruthy()
expect(content).toMatch(/(\/_og\/[ds]\/).+\.png$/)
}
}

export const testOgImage = (paths: {
Expand Down
9 changes: 5 additions & 4 deletions tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@
"test:e2e": "playwright test",
"test:e2e:docker:br": "pnpm run test:e2e:docker:build && pnpm run test:e2e:docker:run",
"test:e2e:docker:build": "sudo docker build -t test-e2e_development --build-arg UID=$(id -u) --build-arg GID=$(id -g) --target test-e2e_development ..",
"test:e2e:docker:run": "sudo docker run --rm -v \"$PWD/..:/srv/app\" -v \"vibetype_playwright_data:/srv/app/node_modules\" -v \"$(pnpm store path):/srv/.pnpm-store\" test-e2e_development",
"test:e2e:docker:run": "sudo docker run --add-host=app.localhost:127.0.0.1 --rm -v \"$PWD/..:/srv/app\" -v \"vibetype_playwright_data:/srv/app/node_modules\" -v \"$(pnpm store path):/srv/.pnpm-store\" test-e2e_development",
"test:e2e:docker:server:dev": "pnpm run test:e2e:docker:br pnpm --dir tests run test:e2e:server:dev",
"test:e2e:docker:server:dev:update": "del-cli e2e/specs/**/*.png && pnpm run test:e2e:docker:server:dev --update-snapshots",
"test:e2e:docker:server:node": "pnpm run test:e2e:docker:br pnpm --dir tests run test:e2e:server:node",
"test:e2e:docker:server:node:update": "del-cli e2e/specs/**/*.png && pnpm run test:e2e:docker:server:node --update-snapshots",
"test:e2e:docker:server:static": "pnpm run test:e2e:docker:br pnpm --dir tests run test:e2e:server:static",
"test:e2e:docker:server:static:update": "del-cli e2e/specs/**/*.png && pnpm run test:e2e:docker:server:static --update-snapshots",
"test:e2e:server:dev": "cross-env PORT=3000 NUXT_PUBLIC_SITE_URL=https://localhost:3000 VIO_SERVER=development pnpm run test:e2e",
"test:e2e:server:node": "cross-env NODE_ENV=production NODE_EXTRA_CA_CERTS=\"$(mkcert -CAROOT)/rootCA.pem\" NUXT_PUBLIC_I18N_BASE_URL=https://localhost:3001 NUXT_PUBLIC_SITE_URL=https://localhost:3001 PORT=3001 VIO_SERVER=node pnpm run test:e2e",
"test:e2e:server:static": "cross-env NODE_ENV=production PORT=3002 NUXT_PUBLIC_SITE_URL=https://localhost:3002 VIO_SERVER=static pnpm run test:e2e"
"test:e2e:server:dev": "cross-env NUXT_PUBLIC_I18N_BASE_URL=https://app.localhost:3000 PORT=3000 VIO_SERVER=development pnpm run test:e2e",
"test:e2e:server:node": "cross-env NODE_EXTRA_CA_CERTS=\"$(mkcert -CAROOT)/rootCA.pem\" NUXT_PUBLIC_I18N_BASE_URL=https://app.localhost:3001 PORT=3001 VIO_SERVER=node pnpm run test:e2e",
"test:e2e:server:static": "cross-env NUXT_PUBLIC_I18N_BASE_URL=https://app.localhost:3002 PORT=3002 VIO_SERVER=static pnpm run test:e2e",
"test:e2e:ui": "pnpm run test:e2e --ui"
},
"type": "module"
}
Loading