@dargmuesli/nuxt-vio 19.0.2 → 19.0.3

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/app/app.config.ts CHANGED
@@ -5,55 +5,57 @@ export default defineAppConfig({
5
5
  },
6
6
  })
7
7
 
8
- export type AppConfig = {
9
- vio: {
10
- pages?: {
11
- legalNotice?: {
12
- contact: {
13
- email: string
14
- }
15
- responsibility: {
16
- address: {
17
- city: string
18
- name: string
19
- street: string
20
- }
21
- }
22
- tmg: {
23
- address: {
24
- city: string
25
- name: string
26
- street: string
8
+ declare module 'nuxt/schema' {
9
+ interface AppConfig {
10
+ vio: {
11
+ pages?: {
12
+ legalNotice?: {
13
+ contact: {
14
+ email: string
27
15
  }
28
- }
29
- }
30
- privacyPolicy?: {
31
- hostingCdn?: {
32
- external: {
16
+ responsibility: {
33
17
  address: {
34
18
  city: string
35
19
  name: string
36
20
  street: string
37
21
  }
38
22
  }
39
- }
40
- mandatoryInfo?: {
41
- responsible: {
23
+ tmg: {
42
24
  address: {
43
25
  city: string
44
- email: string
45
26
  name: string
46
27
  street: string
47
28
  }
48
29
  }
49
30
  }
31
+ privacyPolicy?: {
32
+ hostingCdn?: {
33
+ external: {
34
+ address: {
35
+ city: string
36
+ name: string
37
+ street: string
38
+ }
39
+ }
40
+ }
41
+ mandatoryInfo?: {
42
+ responsible: {
43
+ address: {
44
+ city: string
45
+ email: string
46
+ name: string
47
+ street: string
48
+ }
49
+ }
50
+ }
51
+ }
50
52
  }
51
- }
52
- server?: {
53
- middleware: {
54
- headers: Record<string, string>
53
+ server?: {
54
+ middleware: {
55
+ headers: Record<string, string>
56
+ }
55
57
  }
58
+ themeColor?: string
56
59
  }
57
- themeColor?: string
58
60
  }
59
61
  }
@@ -1,53 +1,72 @@
1
1
  <template>
2
2
  <VioLayoutProse class="m-auto">
3
3
  <h1>{{ title }}</h1>
4
- <h2>{{ t('tmg') }}</h2>
5
- <address>
6
- <slot v-if="$slots.tmgAddress" name="tmgAddress" />
7
- <i18n-t v-else keypath="tmgAddress">
8
- <template #br>
9
- <br />
10
- </template>
11
- <template #city>
12
- {{ appConfig.vio.pages.legalNotice.tmg.address.city }}
13
- </template>
14
- <template #name>
15
- {{ appConfig.vio.pages.legalNotice.tmg.address.name }}
16
- </template>
17
- <template #street>
18
- {{ appConfig.vio.pages.legalNotice.tmg.address.street }}
19
- </template>
20
- </i18n-t>
21
- </address>
22
4
 
23
- <h2>{{ t('contact') }}</h2>
24
- <p>
25
- <slot v-if="$slots.contactEmail" name="contactEmail" />
26
- <span v-else>
27
- {{
28
- t('email', { email: appConfig.vio.pages.legalNotice.contact.email })
29
- }}
30
- </span>
31
- </p>
5
+ <section
6
+ v-if="appConfig.vio.pages?.legalNotice"
7
+ :aria-labelledby="templateIdTmg"
8
+ >
9
+ <h2 :id="templateIdTmg">{{ t('tmg') }}</h2>
10
+ <address>
11
+ <slot v-if="$slots.tmgAddress" name="tmgAddress" />
12
+ <i18n-t v-else keypath="tmgAddress">
13
+ <template #br>
14
+ <br />
15
+ </template>
16
+ <template #city>
17
+ {{ appConfig.vio.pages.legalNotice.tmg.address.city }}
18
+ </template>
19
+ <template #name>
20
+ {{ appConfig.vio.pages.legalNotice.tmg.address.name }}
21
+ </template>
22
+ <template #street>
23
+ {{ appConfig.vio.pages.legalNotice.tmg.address.street }}
24
+ </template>
25
+ </i18n-t>
26
+ </address>
27
+ </section>
32
28
 
33
- <h2>{{ t('responsibility') }}</h2>
34
- <address>
35
- <slot v-if="$slots.responsibilityAddress" name="responsibilityAddress" />
36
- <i18n-t v-else keypath="responsibilityAddress">
37
- <template #br>
38
- <br />
39
- </template>
40
- <template #city>
41
- {{ appConfig.vio.pages.legalNotice.responsibility.address.city }}
42
- </template>
43
- <template #name>
44
- {{ appConfig.vio.pages.legalNotice.responsibility.address.name }}
45
- </template>
46
- <template #street>
47
- {{ appConfig.vio.pages.legalNotice.responsibility.address.street }}
48
- </template>
49
- </i18n-t>
50
- </address>
29
+ <section
30
+ v-if="appConfig.vio.pages?.legalNotice"
31
+ :aria-labelledby="templateIdContact"
32
+ >
33
+ <h2 :id="templateIdContact">{{ t('contact') }}</h2>
34
+ <p>
35
+ <slot v-if="$slots.contactEmail" name="contactEmail" />
36
+ <span v-else>
37
+ {{
38
+ t('email', { email: appConfig.vio.pages.legalNotice.contact.email })
39
+ }}
40
+ </span>
41
+ </p>
42
+ </section>
43
+
44
+ <section
45
+ v-if="appConfig.vio.pages?.legalNotice"
46
+ :aria-labelledby="templateIdResponsibility"
47
+ >
48
+ <h2 :id="templateIdResponsibility">{{ t('responsibility') }}</h2>
49
+ <address>
50
+ <slot
51
+ v-if="$slots.responsibilityAddress"
52
+ name="responsibilityAddress"
53
+ />
54
+ <i18n-t v-else keypath="responsibilityAddress">
55
+ <template #br>
56
+ <br />
57
+ </template>
58
+ <template #city>
59
+ {{ appConfig.vio.pages.legalNotice.responsibility.address.city }}
60
+ </template>
61
+ <template #name>
62
+ {{ appConfig.vio.pages.legalNotice.responsibility.address.name }}
63
+ </template>
64
+ <template #street>
65
+ {{ appConfig.vio.pages.legalNotice.responsibility.address.street }}
66
+ </template>
67
+ </i18n-t>
68
+ </address>
69
+ </section>
51
70
 
52
71
  <h3>{{ t('liabilityContentTitle') }}</h3>
53
72
  <p>{{ t('liabilityContentDescription1') }}</p>
@@ -73,6 +92,11 @@ const { t } = useI18n()
73
92
 
74
93
  // data
75
94
  const title = t('title')
95
+
96
+ // template
97
+ const templateIdContact = useId()
98
+ const templateIdResponsibility = useId()
99
+ const templateIdTmg = useId()
76
100
  </script>
77
101
 
78
102
  <i18n lang="yaml">
@@ -44,7 +44,11 @@
44
44
  </section>
45
45
  </section>
46
46
  </li>
47
- <li v-if="isEnabled.hostingCdn">
47
+ <li
48
+ v-if="
49
+ isEnabled.hostingCdn && appConfig.vio.pages?.privacyPolicy?.hostingCdn
50
+ "
51
+ >
48
52
  <section>
49
53
  <h2>{{ t('hostingCdn') }}</h2>
50
54
 
@@ -102,7 +106,12 @@
102
106
  <p>{{ t('mandatoryInfoPrivacyDescription3') }}</p>
103
107
  </section>
104
108
 
105
- <section v-if="isEnabled.mandatoryInfo.responsible">
109
+ <section
110
+ v-if="
111
+ isEnabled.mandatoryInfo.responsible &&
112
+ appConfig.vio.pages?.privacyPolicy?.mandatoryInfo
113
+ "
114
+ >
106
115
  <h3>{{ t('mandatoryInfoResponsibleTitle') }}</h3>
107
116
  <p>{{ t('mandatoryInfoResponsibleDescription1') }}</p>
108
117
  <address>
package/nuxt.config.ts CHANGED
@@ -65,11 +65,6 @@ export default defineNuxtConfig(
65
65
  ) {
66
66
  if (nuxt.options.nitro.static) {
67
67
  nuxtConfigSecurityHeaders.contentSecurityPolicy = defu(
68
- {
69
- 'script-src-elem': [
70
- "'unsafe-inline'", // TODO: remove (https://github.com/Baroshem/nuxt-security/pull/659)
71
- ],
72
- },
73
68
  VIO_GET_CSP({ siteUrl: new URL(SITE_URL) }),
74
69
  nuxtConfigSecurityHeaders.contentSecurityPolicy,
75
70
  )
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
- "@dargmuesli/nuxt-cookie-control": "9.1.7",
4
- "@eslint/compat": "1.4.1",
3
+ "@dargmuesli/nuxt-cookie-control": "9.1.8",
4
+ "@eslint/compat": "2.0.0",
5
5
  "@heroicons/vue": "2.2.0",
6
6
  "@http-util/status-i18n": "0.9.0",
7
7
  "@intlify/eslint-plugin-vue-i18n": "4.1.0",
@@ -10,7 +10,7 @@
10
10
  "@nuxt/image": "2.0.0",
11
11
  "@nuxtjs/color-mode": "4.0.0",
12
12
  "@nuxtjs/html-validator": "2.1.0",
13
- "@nuxtjs/i18n": "10.2.0",
13
+ "@nuxtjs/i18n": "10.2.1",
14
14
  "@nuxtjs/seo": "3.2.2",
15
15
  "@pinia/nuxt": "0.11.3",
16
16
  "@tailwindcss/forms": "0.5.10",
@@ -21,7 +21,7 @@
21
21
  "@urql/vue": "2.0.0",
22
22
  "@vuelidate/core": "2.0.3",
23
23
  "@vuelidate/validators": "2.0.4",
24
- "clipboardy": "5.0.0",
24
+ "clipboardy": "5.0.1",
25
25
  "dayjs": "2.0.0-alpha.4",
26
26
  "eslint": "9.39.1",
27
27
  "eslint-config-prettier": "10.1.8",
@@ -30,14 +30,14 @@
30
30
  "eslint-plugin-yml": "1.19.0",
31
31
  "globals": "16.5.0",
32
32
  "jiti": "2.6.1",
33
- "jose": "6.1.1",
33
+ "jose": "6.1.2",
34
34
  "nuxt-gtag": "4.1.0",
35
- "nuxt-security": "2.4.0",
35
+ "nuxt-security": "2.5.0",
36
36
  "sweetalert2": "11.26.3",
37
- "vue-tsc": "3.1.3"
37
+ "vue-tsc": "3.1.4"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "24.10.0",
40
+ "@types/node": "24.10.1",
41
41
  "@urql/devtools": "2.0.3",
42
42
  "@urql/exchange-graphcache": "8.1.0",
43
43
  "consola": "3.4.2",
@@ -50,7 +50,7 @@
50
50
  "prettier-plugin-tailwindcss": "0.7.1",
51
51
  "serve": "14.2.5",
52
52
  "sharp": "0.34.5",
53
- "stylelint": "16.25.0",
53
+ "stylelint": "16.26.0",
54
54
  "stylelint-config-recommended-vue": "1.6.1",
55
55
  "stylelint-config-standard": "39.0.1",
56
56
  "stylelint-no-unsupported-browser-features": "8.0.5",
@@ -106,5 +106,5 @@
106
106
  "start:static": "serve playground/.output/public --ssl-cert ./.config/certificates/ssl.crt --ssl-key ./.config/certificates/ssl.key"
107
107
  },
108
108
  "type": "module",
109
- "version": "19.0.2"
109
+ "version": "19.0.3"
110
110
  }
@@ -1,5 +1,7 @@
1
+ import type { AppConfig } from 'nuxt/schema'
2
+
1
3
  export default defineEventHandler(async (event) => {
2
- const config = useAppConfig() as AppConfig
4
+ const config = useAppConfig(event) as AppConfig
3
5
 
4
6
  if (!config.vio.server) return
5
7
 
@@ -1,9 +1,9 @@
1
1
  import { defu } from 'defu'
2
- import type { NuxtOptions } from 'nuxt/schema'
2
+ import type { ModuleOptions } from 'nuxt-security'
3
3
 
4
4
  // remove invalid `'none'`s and duplicates
5
5
  export const cleanupCsp = (
6
- nuxtSecurityConfiguration: Partial<NuxtOptions['security']>,
6
+ nuxtSecurityConfiguration: Partial<ModuleOptions>,
7
7
  ) => {
8
8
  if (
9
9
  nuxtSecurityConfiguration.headers &&
@@ -4,6 +4,6 @@ export const useSiteUrl = () => {
4
4
 
5
5
  return {
6
6
  siteUrl,
7
- siteUrlTyped: new URL(siteUrl), // eslint-disable-line compat/compat
7
+ siteUrlTyped: new URL(siteUrl),
8
8
  }
9
9
  }
@@ -1,5 +1,6 @@
1
1
  import type { Validation } from '@vuelidate/core'
2
2
  import { consola } from 'consola'
3
+ import type { Ref } from 'vue'
3
4
 
4
5
  export const isFormValid = async ({
5
6
  v$,
@@ -1,7 +1,10 @@
1
1
  import type { CombinedError } from '@urql/core'
2
2
  import type { H3Event } from 'h3'
3
+ import { computed, reactive } from 'vue'
3
4
  import type { Ref } from 'vue'
4
5
 
6
+ import type { ApiData, BackendError } from '../types/api'
7
+
5
8
  export const getApiDataDefault = (): ApiData =>
6
9
  computed(() =>
7
10
  reactive({
@@ -1,3 +1,5 @@
1
+ import type { defineNuxtConfig } from 'nuxt/config'
2
+
1
3
  import { I18N_MODULE_CONFIG } from './constants'
2
4
 
3
5
  export const VIO_NUXT_BASE_CONFIG = ({
@@ -1,4 +1,4 @@
1
- import type { RouteLocationRaw } from '#vue-router'
1
+ import type { RouteLocationRaw } from 'vue-router'
2
2
 
3
3
  export const append = (path: string, pathToAppend?: RouteLocationRaw) =>
4
4
  path + (path.endsWith('/') ? '' : '/') + (pathToAppend ?? '')
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "../playground/.nuxt/tsconfig.server.json"
3
- }
@@ -1,126 +0,0 @@
1
- import type { Client } from '@urql/vue'
2
- import { consola } from 'consola'
3
- import { setCookie } from 'h3'
4
- import type { H3Event } from 'h3'
5
- import { decodeJwt } from 'jose'
6
-
7
- import { useVioAuthStore } from '../../app/stores/auth'
8
-
9
- export const getJwtFromCookie = () => {
10
- const cookie = useCookie(JWT_NAME())
11
-
12
- if (!cookie.value) {
13
- consola.debug('No token cookie.')
14
- return
15
- }
16
-
17
- const jwt = decodeJwt(cookie.value)
18
-
19
- if (jwt.exp === undefined || jwt.exp <= Date.now() / 1000) {
20
- consola.info('Token expired.')
21
- return
22
- }
23
-
24
- return {
25
- jwt: cookie.value,
26
- jwtDecoded: jwt,
27
- }
28
- }
29
-
30
- export const jwtStore = async ({
31
- $urqlReset,
32
- event,
33
- isInProduction,
34
- jwt,
35
- store,
36
- }: {
37
- $urqlReset: () => Client
38
- event?: H3Event
39
- isInProduction: boolean
40
- jwt?: string
41
- store: ReturnType<typeof useVioAuthStore>
42
- }) => {
43
- $urqlReset()
44
-
45
- consola.trace('Storing the following JWT: ' + jwt)
46
- store.jwtSet(jwt)
47
-
48
- if (event) {
49
- setCookie(event, JWT_NAME(), jwt || '', {
50
- expires: jwt ? new Date(Date.now() + 86400 * 1000 * 31) : new Date(0),
51
- httpOnly: true,
52
- path: '/',
53
- sameSite: 'lax', // Cannot be 'strict' to allow authentications after clicking on links within webmailers.
54
- secure: isInProduction,
55
- })
56
- } else {
57
- try {
58
- await $fetch('/api/auth', {
59
- method: 'POST',
60
- ...(jwt ? { headers: { Authorization: `Bearer ${jwt}` } } : {}),
61
- })
62
- } catch (error) {
63
- console.error(error)
64
- return Promise.reject(Error('Authentication api call failed.'))
65
- }
66
- }
67
- }
68
-
69
- export const useJwtStore = () => {
70
- const { $urqlReset, ssrContext } = useNuxtApp()
71
- const store = useVioAuthStore()
72
- const runtimeConfig = useRuntimeConfig()
73
-
74
- return {
75
- async jwtStore(jwt?: string) {
76
- await jwtStore({
77
- $urqlReset: $urqlReset as () => Client,
78
- event: ssrContext?.event,
79
- isInProduction: runtimeConfig.public.vio.isInProduction,
80
- jwt,
81
- store,
82
- })
83
- },
84
- }
85
- }
86
-
87
- export const signOut = async ({
88
- $urqlReset,
89
- // client,
90
- event,
91
- isInProduction,
92
- store,
93
- }: {
94
- $urqlReset: () => Client
95
- client: Client
96
- event?: H3Event
97
- isInProduction: boolean
98
- store: ReturnType<typeof useVioAuthStore>
99
- }) => {
100
- await jwtStore({ $urqlReset, event, isInProduction, store })
101
- // await authenticationAnonymous({
102
- // $urqlReset,
103
- // client,
104
- // event,
105
- // isInProduction,
106
- // store,
107
- // })
108
- }
109
-
110
- export const useSignOut = () => {
111
- const { $urql, $urqlReset, ssrContext } = useNuxtApp()
112
- const store = useVioAuthStore()
113
- const runtimeConfig = useRuntimeConfig()
114
-
115
- return {
116
- async signOut() {
117
- await signOut({
118
- $urqlReset: $urqlReset as () => Client,
119
- client: ($urql as Ref<Client>).value,
120
- event: ssrContext?.event,
121
- isInProduction: runtimeConfig.public.vio.isInProduction,
122
- store,
123
- })
124
- },
125
- }
126
- }
File without changes