create-nuxt-base 0.3.16 → 1.0.2

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.
Files changed (64) hide show
  1. package/.github/workflows/publish.yml +4 -2
  2. package/.oxfmtrc.jsonc +7 -0
  3. package/CHANGELOG.md +22 -8
  4. package/nuxt-base-template/.dockerignore +44 -0
  5. package/nuxt-base-template/.env.example +1 -1
  6. package/nuxt-base-template/.nuxtrc +1 -0
  7. package/nuxt-base-template/.oxfmtrc.jsonc +8 -0
  8. package/nuxt-base-template/Dockerfile.dev +23 -0
  9. package/nuxt-base-template/README.md +127 -13
  10. package/nuxt-base-template/app/app.config.ts +67 -0
  11. package/nuxt-base-template/app/app.vue +10 -2
  12. package/nuxt-base-template/app/assets/css/tailwind.css +124 -84
  13. package/nuxt-base-template/app/components/Modal/ModalBackupCodes.vue +117 -0
  14. package/nuxt-base-template/app/components/Modal/ModalBase.vue +65 -0
  15. package/nuxt-base-template/app/components/Transition/TransitionSlide.vue +0 -2
  16. package/nuxt-base-template/app/components/Transition/TransitionSlideBottom.vue +0 -2
  17. package/nuxt-base-template/app/components/Transition/TransitionSlideRevert.vue +0 -2
  18. package/nuxt-base-template/app/components/Upload/TusFileUpload.vue +302 -0
  19. package/nuxt-base-template/app/composables/use-better-auth.ts +25 -0
  20. package/nuxt-base-template/app/composables/use-file.ts +57 -6
  21. package/nuxt-base-template/app/composables/use-share.ts +26 -10
  22. package/nuxt-base-template/app/composables/use-tus-upload.ts +278 -0
  23. package/nuxt-base-template/app/error.vue +7 -43
  24. package/nuxt-base-template/app/interfaces/upload.interface.ts +58 -0
  25. package/nuxt-base-template/app/interfaces/user.interface.ts +12 -0
  26. package/nuxt-base-template/app/layouts/default.vue +76 -4
  27. package/nuxt-base-template/app/layouts/slim.vue +5 -0
  28. package/nuxt-base-template/app/lib/auth-client.ts +135 -0
  29. package/nuxt-base-template/app/middleware/admin.global.ts +20 -6
  30. package/nuxt-base-template/app/middleware/auth.global.ts +15 -6
  31. package/nuxt-base-template/app/middleware/guest.global.ts +18 -0
  32. package/nuxt-base-template/app/pages/app/settings/security.vue +409 -0
  33. package/nuxt-base-template/app/pages/auth/2fa.vue +120 -0
  34. package/nuxt-base-template/app/pages/auth/forgot-password.vue +115 -0
  35. package/nuxt-base-template/app/pages/auth/login.vue +135 -0
  36. package/nuxt-base-template/app/pages/auth/register.vue +184 -0
  37. package/nuxt-base-template/app/pages/auth/reset-password.vue +153 -0
  38. package/nuxt-base-template/app/pages/index.vue +139 -2
  39. package/nuxt-base-template/app/utils/crypto.ts +13 -0
  40. package/nuxt-base-template/docker-entrypoint.sh +21 -0
  41. package/nuxt-base-template/docs/nuxt.config.ts +4 -0
  42. package/nuxt-base-template/docs/pages/docs.vue +663 -0
  43. package/nuxt-base-template/nuxt.config.ts +75 -30
  44. package/nuxt-base-template/openapi-ts.config.ts +18 -0
  45. package/nuxt-base-template/oxlint.json +14 -0
  46. package/nuxt-base-template/package-lock.json +11414 -15883
  47. package/nuxt-base-template/package.json +48 -50
  48. package/nuxt-base-template/tests/iam.spec.ts +247 -0
  49. package/nuxt-base-template/tsconfig.json +1 -1
  50. package/package.json +15 -12
  51. package/.eslintignore +0 -14
  52. package/.eslintrc +0 -3
  53. package/.prettierignore +0 -5
  54. package/.prettierrc +0 -6
  55. package/nuxt-base-template/app/composables/use-context-menu.ts +0 -19
  56. package/nuxt-base-template/app/composables/use-form-helper.ts +0 -41
  57. package/nuxt-base-template/app/composables/use-modal.ts +0 -84
  58. package/nuxt-base-template/app/composables/use-notification.ts +0 -29
  59. package/nuxt-base-template/app/middleware/logged-in.global.ts +0 -9
  60. package/nuxt-base-template/app/plugins/auth.server.ts +0 -72
  61. package/nuxt-base-template/app/plugins/form.plugin.ts +0 -21
  62. package/nuxt-base-template/app/plugins/pwa.plugin.ts +0 -114
  63. package/nuxt-base-template/eslint.config.mjs +0 -3
  64. package/nuxt-base-template/tailwind.config.js +0 -21
@@ -1,72 +0,0 @@
1
- import { callWithNuxt, defineNuxtPlugin, useNuxtApp, useRuntimeConfig } from 'nuxt/app';
2
- import { ofetch } from 'ofetch';
3
-
4
- export default defineNuxtPlugin({
5
- dependsOn: ['cookies', 'graphql-meta'], // from nuxt-base
6
- name: 'auth-server',
7
- async setup() {
8
- const _nuxt = useNuxtApp();
9
- const config = await callWithNuxt(_nuxt, useRuntimeConfig);
10
- const { accessTokenState, currentUserState, refreshTokenState } = await callWithNuxt(_nuxt, useAuthState);
11
- const { clearSession, getDecodedAccessToken, isTokenExpired, setCurrentUser, setTokens } = await callWithNuxt(_nuxt, useAuth);
12
- const payload = accessTokenState.value ? getDecodedAccessToken(accessTokenState.value) : null;
13
-
14
- if (!accessTokenState.value || !refreshTokenState.value || currentUserState.value) {
15
- return;
16
- }
17
-
18
- let token = accessTokenState.value;
19
- if (isTokenExpired(accessTokenState.value)) {
20
- const refreshTokenResult = await ofetch(config.public.gqlHost, {
21
- body: JSON.stringify({
22
- query: 'mutation refreshToken {refreshToken {token, refreshToken}}',
23
- variables: {},
24
- }),
25
- headers: {
26
- Authorization: `Bearer ${refreshTokenState.value}`,
27
- },
28
- method: 'POST',
29
- }).catch((err) => {
30
- console.error('2.auth.server.ts::refreshToken::catch', err.data);
31
- clearSession();
32
- navigateTo('/auth');
33
- });
34
-
35
- const data = refreshTokenResult?.data?.refreshToken;
36
- if (data) {
37
- setTokens(data.token, data.refreshToken);
38
- token = data?.token;
39
- } else {
40
- clearSession();
41
- await navigateTo('/auth');
42
- }
43
- }
44
-
45
- if (token && payload?.id) {
46
- const userResult = await ofetch(config.public.gqlHost, {
47
- body: JSON.stringify({
48
- query: 'query getUser($id: String!){' + 'getUser(id: $id){' + 'id ' + 'firstName ' + 'lastName ' + 'email ' + 'roles ' + '}}',
49
- variables: {
50
- id: payload.id,
51
- },
52
- }),
53
- headers: {
54
- Authorization: `Bearer ${token}`,
55
- },
56
- method: 'POST',
57
- }).catch((err) => {
58
- console.error('2.auth.server.ts::getUser::catch', err);
59
- });
60
-
61
- if (userResult?.errors) {
62
- clearSession();
63
- navigateTo('/auth');
64
- return;
65
- }
66
-
67
- if (userResult?.data) {
68
- setCurrentUser(userResult?.data?.getUser);
69
- }
70
- }
71
- },
72
- });
@@ -1,21 +0,0 @@
1
- import { setLocale } from 'yup';
2
-
3
- export default defineNuxtPlugin(async () => {
4
- setLocale({
5
- // use constant translation keys for messages without values
6
- mixed: {
7
- default: 'Dieses Feld ist ungültig.',
8
- notType: 'Dieses Feld ist ungültig.',
9
- required: 'Dieses Feld ist erforderlich.',
10
- },
11
- string: {
12
- email: 'Bitte geben Sie eine gültige E-Mail-Adresse ein.',
13
- },
14
- });
15
-
16
- // Custom validation rules
17
- // https://github.com/jquense/yup?tab=readme-ov-file#addmethodschematype-schema-name-string-method--schema-void
18
- // addMethod(string, 'plz', () => {
19
- // return
20
- // });
21
- });
@@ -1,114 +0,0 @@
1
- export default defineNuxtPlugin(async () => {
2
- const applicationServerKey = useRuntimeConfig().public.webPushKey as string;
3
- const permissionState = ref<PermissionState>('prompt');
4
- const subscription = ref<null | PushSubscription>(null);
5
-
6
- if (process.client) {
7
- const iosPWASplash = (await import('ios-pwa-splash')).default;
8
- iosPWASplash('/notification.png', '#FFFFFF');
9
- }
10
-
11
- async function subscribe() {
12
- const sw = await navigator.serviceWorker.ready;
13
- const push = await sw.pushManager.subscribe({
14
- applicationServerKey,
15
- userVisibleOnly: true,
16
- });
17
- await refreshSubscription();
18
- await refreshPermissionState();
19
- const body = {
20
- payload: push,
21
- };
22
- try {
23
- await useAuthFetch('/web-push/subscribe', {
24
- baseURL: process.env.API_URL,
25
- body,
26
- method: 'POST',
27
- });
28
- } catch (e) {
29
- console.error(e);
30
- }
31
- }
32
-
33
- async function refreshPermissionState() {
34
- try {
35
- const sw = await navigator.serviceWorker.ready;
36
- permissionState.value = await sw.pushManager.permissionState({
37
- applicationServerKey,
38
- userVisibleOnly: true,
39
- });
40
- } catch (e) {
41
- console.error(e);
42
- }
43
- }
44
-
45
- async function refreshSubscription() {
46
- try {
47
- const sw = await navigator.serviceWorker.ready;
48
- subscription.value = await sw.pushManager.getSubscription();
49
- } catch (e) {
50
- console.error(e);
51
- }
52
- }
53
-
54
- async function unsubscribe() {
55
- if (subscription.value) {
56
- await subscription.value.unsubscribe();
57
- const body = {
58
- payload: subscription.value,
59
- };
60
- await refreshPermissionState();
61
- try {
62
- await useAuthFetch('/web-push/', {
63
- baseURL: process.env.API_URL,
64
- body,
65
- method: 'DELETE',
66
- });
67
- } catch (e) {
68
- console.error(e);
69
- }
70
- subscription.value = null;
71
- }
72
- }
73
-
74
- const route = useRoute();
75
- const pwa = ref(false);
76
- const isPwa = computed(() => route.query.standalone === 'true' || pwa.value);
77
-
78
- if (process.client) {
79
- if (window && window.matchMedia && document && window.matchMedia('(display-mode: standalone)').matches) {
80
- if (navigator && navigator.serviceWorker) {
81
- await refreshSubscription();
82
- await refreshPermissionState();
83
- }
84
- pwa.value = true;
85
- document.body.classList.add('select-none', 'overscroll-y-none', 'no-scrollbar', 'bg-rm-gray-1');
86
- } else {
87
- pwa.value = false;
88
- document.body.classList.remove('select-none', 'overscroll-y-none', 'no-scrollbar', 'bg-rm-gray-1');
89
- }
90
- }
91
-
92
- useHead({
93
- htmlAttrs: { class: isPwa.value ? 'pwa' : '' },
94
- meta: [
95
- {
96
- content: 'width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no',
97
- hid: 'viewport',
98
- name: 'viewport',
99
- },
100
- ],
101
- });
102
-
103
- return {
104
- provide: {
105
- pwa: {
106
- isPwa: () => isPwa.value,
107
- permissionState,
108
- subscribe,
109
- subscription,
110
- unsubscribe,
111
- },
112
- },
113
- };
114
- });
@@ -1,3 +0,0 @@
1
- import vue from '@lenne.tech/eslint-config-vue';
2
-
3
- export default vue;
@@ -1,21 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- // eslint-disable-next-line @typescript-eslint/no-require-imports
3
- const { iconsPlugin, getIconCollections } = require('@egoist/tailwindcss-icons');
4
- // eslint-disable-next-line @typescript-eslint/no-require-imports
5
- const plugin = require('tailwindcss/plugin');
6
-
7
- module.exports = {
8
- plugins: [
9
- iconsPlugin({
10
- // Select the icon collections you want to use
11
- collections: getIconCollections(['bi']),
12
- }),
13
- plugin(({ addVariant, e }) => {
14
- addVariant('pwa', ({ modifySelectors, separator }) => {
15
- modifySelectors(({ className }) => {
16
- return `.pwa .${e(`pwa${separator}${className}`)}`;
17
- });
18
- });
19
- }),
20
- ],
21
- };