@fdm-monster/client-next 0.0.1 → 0.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.
Files changed (199) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/RELEASE_NOTES.MD +28 -1
  3. package/dist/assets/MaterialIcons-Regular-BjXOXp5c.eot +0 -0
  4. package/dist/assets/MaterialIcons-Regular-DEUTIz1o.ttf +0 -0
  5. package/dist/assets/MaterialIcons-Regular-DOtZ65Va.woff2 +0 -0
  6. package/dist/assets/MaterialIcons-Regular-FsbMSDLx.woff +0 -0
  7. package/dist/assets/index-CHzfWKPO.css +5 -0
  8. package/dist/assets/index-WVqTlgq7.js +90 -0
  9. package/dist/assets/index-WVqTlgq7.js.map +1 -0
  10. package/dist/favicon.ico +0 -0
  11. package/dist/img/DavidZwart.jpg +0 -0
  12. package/dist/img/OIG.JYDC2RaWdz7g9.jpg +0 -0
  13. package/dist/img/OIG.jpg +0 -0
  14. package/dist/img/icons/android-chrome-256x256.png +0 -0
  15. package/dist/img/icons/android-chrome-384x384.png +0 -0
  16. package/dist/img/icons/android-chrome-512x512.png +0 -0
  17. package/dist/img/icons/favicon.svg +1 -0
  18. package/dist/img/logo.png +0 -0
  19. package/dist/img/logo.svg +1 -0
  20. package/dist/img/manifest.webmanifest +33 -0
  21. package/dist/img/octoprint-tentacle.svg +144 -0
  22. package/dist/img/thumbail_unknown.jpg +0 -0
  23. package/dist/img/vbanner.jpg +0 -0
  24. package/dist/index.html +24 -0
  25. package/dist/robots.txt +2 -0
  26. package/package.json +1 -1
  27. package/.all-contributorsrc +0 -57
  28. package/.editorconfig +0 -5
  29. package/.eslintrc.js +0 -126
  30. package/.github/FUNDING.yml +0 -3
  31. package/.github/workflows/release-client.yml +0 -94
  32. package/.github/workflows/vue-publish.yml +0 -26
  33. package/.prettierignore +0 -15
  34. package/.whitesource +0 -12
  35. package/renovate.json +0 -30
  36. package/src/App.vue +0 -60
  37. package/src/AppLoader.vue +0 -383
  38. package/src/assets/adjectives.json +0 -1468
  39. package/src/assets/logo.svg +0 -6
  40. package/src/assets/nouns.json +0 -4309
  41. package/src/auto-imports.d.ts +0 -139
  42. package/src/backend/app.service.ts +0 -39
  43. package/src/backend/auth.service.ts +0 -56
  44. package/src/backend/base.service.ts +0 -57
  45. package/src/backend/batch.service.ts +0 -37
  46. package/src/backend/camera-stream.service.ts +0 -33
  47. package/src/backend/custom-gcode.service.ts +0 -11
  48. package/src/backend/dto/octoprint-settings.dto.ts +0 -168
  49. package/src/backend/first-time-setup.service.ts +0 -17
  50. package/src/backend/floor.service.ts +0 -84
  51. package/src/backend/index.ts +0 -4
  52. package/src/backend/print-completions.service.ts +0 -11
  53. package/src/backend/printer-file.service.ts +0 -91
  54. package/src/backend/printer-group.service.ts +0 -62
  55. package/src/backend/printer-job.service.ts +0 -20
  56. package/src/backend/printer-settings.service.ts +0 -28
  57. package/src/backend/printers.service.ts +0 -136
  58. package/src/backend/server-private.service.ts +0 -55
  59. package/src/backend/server.api.ts +0 -132
  60. package/src/backend/settings.service.ts +0 -85
  61. package/src/backend/user.service.ts +0 -51
  62. package/src/components/AboutHelp/AboutView.vue +0 -164
  63. package/src/components/CameraGrid/CameraGridView.vue +0 -111
  64. package/src/components/FirstTimeSetup/FirstTimeSetupView.vue +0 -354
  65. package/src/components/Generic/Actions/PrinterConnectionAction.vue +0 -56
  66. package/src/components/Generic/Actions/PrinterCreateAction.vue +0 -22
  67. package/src/components/Generic/Actions/PrinterDeleteAction.vue +0 -29
  68. package/src/components/Generic/Actions/PrinterQuickStopAction.vue +0 -35
  69. package/src/components/Generic/Actions/PrinterSettingsAction.vue +0 -35
  70. package/src/components/Generic/Actions/PrinterUrlAction.vue +0 -24
  71. package/src/components/Generic/Actions/RefreshFilesAction.vue +0 -50
  72. package/src/components/Generic/Actions/SyncPrinterNameAction.vue +0 -36
  73. package/src/components/Generic/Dialogs/AddOrUpdateCameraStreamDialog.vue +0 -131
  74. package/src/components/Generic/Dialogs/AddOrUpdateFloorDialog.vue +0 -141
  75. package/src/components/Generic/Dialogs/AddOrUpdatePrinterDialog.vue +0 -303
  76. package/src/components/Generic/Dialogs/BaseDialog.vue +0 -81
  77. package/src/components/Generic/Dialogs/BatchJsonCreateDialog.vue +0 -109
  78. package/src/components/Generic/Dialogs/BatchReprintDialog.vue +0 -190
  79. package/src/components/Generic/Dialogs/PrinterChecksPanel.vue +0 -37
  80. package/src/components/Generic/Dialogs/PrinterControlDialog.vue +0 -202
  81. package/src/components/Generic/Dialogs/PrinterMaintenanceDialog.vue +0 -130
  82. package/src/components/Generic/Dialogs/YamlImportExportDialog.vue +0 -186
  83. package/src/components/Generic/Dialogs/dialog.constants.ts +0 -19
  84. package/src/components/Generic/FileExplorerSideNav.vue +0 -734
  85. package/src/components/Generic/Loaders/GridLoader.vue +0 -68
  86. package/src/components/Generic/NavigationDrawer.vue +0 -69
  87. package/src/components/Generic/PrintJobsMenu.vue +0 -148
  88. package/src/components/Generic/Snackbars/AppErrorSnackbar.vue +0 -64
  89. package/src/components/Generic/Snackbars/AppInfoSnackbar.vue +0 -63
  90. package/src/components/Generic/Snackbars/AppProgressSnackbar.vue +0 -158
  91. package/src/components/Generic/Vuetify/TooltipButton.vue +0 -47
  92. package/src/components/HelpOverlay/HelpOverlay.vue +0 -57
  93. package/src/components/Login/LoginForm.vue +0 -206
  94. package/src/components/Login/LoginView.spec.ts +0 -64
  95. package/src/components/Login/LoginView.vue +0 -65
  96. package/src/components/Login/Logo.vue +0 -13
  97. package/src/components/Login/PermissionDenied.vue +0 -109
  98. package/src/components/Login/RegistrationForm.vue +0 -207
  99. package/src/components/Login/RegistrationView.vue +0 -17
  100. package/src/components/Login/__snapshots__/LoginView.spec.ts.snap +0 -1051
  101. package/src/components/NotFound/NotFoundView.vue +0 -39
  102. package/src/components/PrintStatistics/PrintStatistics.vue +0 -168
  103. package/src/components/PrintStatistics/PrintStatisticsView.vue +0 -15
  104. package/src/components/PrinterGrid/HomeToolbar.vue +0 -90
  105. package/src/components/PrinterGrid/PrinterGrid.vue +0 -164
  106. package/src/components/PrinterGrid/PrinterGridTile.vue +0 -438
  107. package/src/components/PrinterGrid/PrinterGridView.vue +0 -210
  108. package/src/components/PrinterList/FileControlList.vue +0 -40
  109. package/src/components/PrinterList/PrinterDetails.vue +0 -91
  110. package/src/components/PrinterList/PrintersView.vue +0 -492
  111. package/src/components/Settings/AccountSettings.vue +0 -163
  112. package/src/components/Settings/DiagnosticsSettings.vue +0 -137
  113. package/src/components/Settings/EmergencyCommands.vue +0 -265
  114. package/src/components/Settings/FloorSettings.vue +0 -276
  115. package/src/components/Settings/GridSettings.vue +0 -127
  116. package/src/components/Settings/OctoPrintSettings.vue +0 -188
  117. package/src/components/Settings/ServerProtectionSettings.vue +0 -370
  118. package/src/components/Settings/SettingsView.vue +0 -73
  119. package/src/components/Settings/SoftwareUpgradeSettings.vue +0 -297
  120. package/src/components/Settings/UserManagementSettings.vue +0 -257
  121. package/src/components/TopBar.vue +0 -147
  122. package/src/components.d.ts +0 -70
  123. package/src/directives/file-upload.directive.ts +0 -117
  124. package/src/directives/printer-drop-position.directive.ts +0 -92
  125. package/src/env.d.ts +0 -6
  126. package/src/main.ts +0 -76
  127. package/src/models/batch/reprint.dto.ts +0 -79
  128. package/src/models/batch.model.ts +0 -11
  129. package/src/models/camera-streams/camera-stream.ts +0 -19
  130. package/src/models/floors/floor.model.ts +0 -30
  131. package/src/models/octoprint/connection-options.model.ts +0 -8
  132. package/src/models/plugins/firmware-updates/prusa-firmware-release.model.ts +0 -57
  133. package/src/models/print-completions/print-completions.model.ts +0 -49
  134. package/src/models/printers/crud/create-printer.model.ts +0 -26
  135. package/src/models/printers/file-upload-commands.model.ts +0 -4
  136. package/src/models/printers/gcode/gcode-analysis.model.ts +0 -30
  137. package/src/models/printers/printer-current-job.model.ts +0 -90
  138. package/src/models/printers/printer-file.model.ts +0 -48
  139. package/src/models/printers/printer.model.ts +0 -18
  140. package/src/models/server/client-releases.model.ts +0 -27
  141. package/src/models/server/export-yaml.model.ts +0 -11
  142. package/src/models/server/features.model.ts +0 -37
  143. package/src/models/server/github-rate-limit.model.ts +0 -21
  144. package/src/models/server/version.model.ts +0 -14
  145. package/src/models/settings/printer-file-clean-settings.model.ts +0 -5
  146. package/src/models/settings/server-settings.dto.ts +0 -19
  147. package/src/models/settings/settings.model.ts +0 -57
  148. package/src/models/socketio-messages/socketio-message.model.ts +0 -53
  149. package/src/models/uploads/queued-upload.model.ts +0 -12
  150. package/src/models/user.model.ts +0 -15
  151. package/src/plugins/README.md +0 -3
  152. package/src/plugins/index.ts +0 -17
  153. package/src/plugins/vuetify.ts +0 -53
  154. package/src/router/index.ts +0 -192
  155. package/src/router/route-names.ts +0 -14
  156. package/src/router/utils.ts +0 -23
  157. package/src/shared/alert.events.ts +0 -14
  158. package/src/shared/app.constants.ts +0 -23
  159. package/src/shared/auth.constants.ts +0 -34
  160. package/src/shared/dialog.composable.ts +0 -41
  161. package/src/shared/drag.constants.ts +0 -19
  162. package/src/shared/experimental.constants.ts +0 -1
  163. package/src/shared/http-client.ts +0 -162
  164. package/src/shared/noun-adjectives.data.ts +0 -24
  165. package/src/shared/printer-grid.constants.ts +0 -5
  166. package/src/shared/printer-state.constants.ts +0 -194
  167. package/src/shared/snackbar.composable.ts +0 -66
  168. package/src/shared/socketio.service.ts +0 -104
  169. package/src/store/auth.store.ts +0 -255
  170. package/src/store/connection.store.ts +0 -66
  171. package/src/store/dialog.store.ts +0 -114
  172. package/src/store/features.store.ts +0 -57
  173. package/src/store/floor.store.ts +0 -173
  174. package/src/store/grid.store.ts +0 -10
  175. package/src/store/index.ts +0 -4
  176. package/src/store/printer-state.store.ts +0 -246
  177. package/src/store/printer.store.ts +0 -236
  178. package/src/store/profile.store.ts +0 -25
  179. package/src/store/settings.store.ts +0 -64
  180. package/src/store/test-printer.store.ts +0 -70
  181. package/src/store/uploads.store.ts +0 -75
  182. package/src/styles/README.md +0 -3
  183. package/src/styles/settings.scss +0 -10
  184. package/src/types/global.d.ts +0 -15
  185. package/src/utils/array.utils.ts +0 -15
  186. package/src/utils/date.utils.ts +0 -5
  187. package/src/utils/download-file.util.ts +0 -25
  188. package/src/utils/error.utils.ts +0 -3
  189. package/src/utils/file-size.util.ts +0 -11
  190. package/src/utils/id.type.ts +0 -1
  191. package/src/utils/sentry.util.ts +0 -8
  192. package/src/utils/test.util.ts +0 -30
  193. package/src/utils/time.utils.ts +0 -2
  194. package/src/utils/uploads-state.utils.ts +0 -58
  195. package/src/utils/validation.utils.ts +0 -14
  196. package/src/vite-env.d.ts +0 -7
  197. package/test/setup-axios-mock.ts +0 -15
  198. /package/{src/assets/logo.png → dist/assets/logo-CJVdjy51.png} +0 -0
  199. /package/{src/assets → dist/img/icons}/android-chrome-192x192.png +0 -0
@@ -1,206 +0,0 @@
1
- <template>
2
- <v-card
3
- class="pa-4"
4
- elevation="10"
5
- style="border-radius: 10px"
6
- >
7
- <v-card-text>
8
- <v-form>
9
- <label> Username </label>
10
- <v-text-field
11
- v-model="username"
12
- autofocus
13
- name="login"
14
- placeholder="Username"
15
- prepend-icon="mdi-account"
16
- type="text"
17
- variant="underlined"
18
- @keyup.enter="formIsDisabled || login()"
19
- />
20
- <v-text-field
21
- id="password"
22
- v-model="password"
23
- :append-icon="showPassword ? 'visibility_off' : 'visibility'"
24
- :type="showPassword ? 'text' : 'password'"
25
- label="Password"
26
- name="password"
27
- password
28
- prepend-icon="lock"
29
- variant="underlined"
30
- @click:append="showPassword = !showPassword"
31
- @keyup.enter="formIsDisabled || login()"
32
- />
33
- <v-alert
34
- v-if="errorMessage"
35
- class="mt-6"
36
- color="error"
37
- density="compact"
38
- variant="outlined"
39
- >
40
- {{ errorMessage }}
41
- </v-alert>
42
- <v-alert
43
- v-if="authStore.lastLogoutReason"
44
- class="mt-6"
45
- color="error-darken-1"
46
- density="compact"
47
- variant="outlined"
48
- >
49
- Reason for automatic logout: {{ authStore.lastLogoutReason }}
50
- </v-alert>
51
- </v-form>
52
- </v-card-text>
53
- <v-card-actions>
54
- <v-btn
55
- :loading="loading"
56
- class="pa-4"
57
- color="primary"
58
- size="lg"
59
- variant="flat"
60
- style="width: 100%"
61
- @click="login()"
62
- >
63
- Login
64
- </v-btn>
65
- </v-card-actions>
66
- <v-card-actions>
67
- <v-btn
68
- :disabled="!authStore.registration"
69
- class="pa-4"
70
- size="lg"
71
- variant="flat"
72
- style="width: 100%"
73
- @click="gotoRegistration()"
74
- >
75
- Register new account {{ authStore.registration ? '' : '(not enabled)' }}
76
- <v-icon
77
- class="pl-5"
78
- icon="right"
79
- />
80
- </v-btn>
81
- </v-card-actions>
82
- </v-card>
83
- </template>
84
-
85
- <script lang="ts" setup>
86
- import { computed, onMounted, ref } from 'vue'
87
- import { useRoute, useRouter } from 'vue-router'
88
- import { useEventBus } from '@vueuse/core'
89
- import { AxiosError } from 'axios'
90
- import { useAuthStore } from '@/store/auth.store'
91
- import { useSnackbar } from '@/shared/snackbar.composable'
92
- import { RouteNames } from '@/router/route-names'
93
- import {
94
- AUTH_ERROR_REASON,
95
- convertAuthErrorReason
96
- } from '@/shared/auth.constants'
97
-
98
- const authStore = useAuthStore()
99
- const errorMessage = ref('')
100
- const username = ref('')
101
- const showPassword = ref(false)
102
- const password = ref('')
103
- const router = useRouter()
104
- const route = useRoute()
105
- const loading = ref(false)
106
- const loginEvent = useEventBus('auth:login')
107
- const snackbar = useSnackbar()
108
-
109
- const formIsDisabled = computed(() => {
110
- return (username.value ?? '')?.length < 3 || (password.value ?? '').length < 3
111
- })
112
-
113
- onMounted(async () => {
114
- authStore.loadTokens()
115
- await authStore.checkAuthenticationRequirements()
116
- if (authStore.loginRequired === false) {
117
- // As AppLoader might not trigger, we trigger it ourselves
118
- console.debug(
119
- 'LoginView, no login required, redirecting to',
120
- route.query.redirect,
121
- 'or home'
122
- )
123
- loginEvent.emit(true)
124
- return await routeToRedirect()
125
- }
126
- if (!authStore.hasRefreshToken) {
127
- return
128
- }
129
-
130
- // Check if login is already valid, if so route away safely
131
- const success = await authStore.verifyOrRefreshLoginOnceOrLogout()
132
- if (success) {
133
- await routeToRedirect()
134
- }
135
- })
136
-
137
- async function gotoRegistration() {
138
- return await router.push({ name: RouteNames.Registration })
139
- }
140
-
141
- async function login() {
142
- try {
143
- loading.value = true
144
- await authStore.login(username.value, password.value)
145
- authStore.lastLogoutReason = null
146
- password.value = ''
147
- loading.value = false
148
- } catch (e) {
149
- loading.value = false
150
- if ((e as AxiosError)?.response?.status === 401) {
151
- password.value = ''
152
-
153
- const reasonCode: keyof typeof AUTH_ERROR_REASON = (
154
- (e as AxiosError)?.response?.data as any
155
- )?.reasonCode
156
- const convertedReason = convertAuthErrorReason(reasonCode)
157
- if (reasonCode === AUTH_ERROR_REASON.AccountNotVerified) {
158
- snackbar.error(
159
- convertedReason,
160
- 'Please ask your administrator to verify your account and try again.'
161
- )
162
- } else if (reasonCode === AUTH_ERROR_REASON.PasswordChangeRequired) {
163
- snackbar.error(
164
- convertedReason,
165
- 'Your password needs to be changed. This feature is sadly not finished'
166
- )
167
- }
168
-
169
- errorMessage.value = convertedReason
170
- return
171
- }
172
-
173
- snackbar.openErrorMessage({
174
- title: 'Error logging in',
175
- subtitle: 'Please test your connection and try again.'
176
- })
177
- errorMessage.value =
178
- 'Error logging in - status code ' + (e as AxiosError)?.response?.status
179
- password.value = ''
180
-
181
- return
182
- }
183
-
184
- errorMessage.value = ''
185
-
186
- // Trigger AppLoader
187
- loginEvent.emit(true)
188
-
189
- return await routeToRedirect()
190
- }
191
-
192
- async function routeToRedirect() {
193
- const routePath = route.query.redirect
194
- if (!routePath) {
195
- console.debug('[LoginForm] Redirecting to home')
196
- await router.push({ name: RouteNames.Home })
197
- return
198
- } else {
199
- console.debug('[LoginForm] Redirecting to ', routePath)
200
- await router.push({
201
- path: routePath as string
202
- })
203
- return
204
- }
205
- }
206
- </script>
@@ -1,64 +0,0 @@
1
- import { mount } from '@vue/test-utils'
2
- import { describe, it, expect, beforeEach } from 'vitest'
3
- import LoginView from '@/components/Login/LoginView.vue' // Adjust the path as necessary
4
- import LoginForm from '@/components/Login/LoginForm.vue'
5
- import Logo from '@/components/Login/Logo.vue'
6
- import { createPinia } from 'pinia'
7
- import { createVuetify } from 'vuetify'
8
- import { createRouter, createWebHistory } from 'vue-router'
9
-
10
- const pinia = createPinia()
11
- const vuetify = createVuetify()
12
- // Create a router for testing
13
- const routes = [{ path: '/', component: LoginView }]
14
- const router = createRouter({
15
- history: createWebHistory(),
16
- routes
17
- })
18
-
19
- describe('LoginView.vue', () => {
20
- let wrapper: ReturnType<typeof mount>
21
-
22
- beforeEach(() => {
23
- wrapper = mount(LoginView, {
24
- global: {
25
- plugins: [vuetify, pinia, router]
26
- }
27
- })
28
- })
29
-
30
- it('renders the logo component', () => {
31
- const logo = wrapper.findComponent(Logo)
32
- expect(logo.exists()).toBe(true)
33
- })
34
-
35
- it('renders the LoginForm component', () => {
36
- const loginForm = wrapper.findComponent(LoginForm)
37
- expect(loginForm.exists()).toBe(true)
38
- })
39
-
40
- it('displays the correct title', () => {
41
- console.log(wrapper.html()) // Log the rendered output for debugging
42
-
43
- const title = wrapper.find('.text-uppercase.text-red') // Using the class selector
44
- expect(title.exists()).toBe(true) // Check if the title exists
45
- expect(title.text()).toContain('FDM')
46
- expect(title.text()).toContain('Monster')
47
- })
48
-
49
- it('displays the correct subtitle', () => {
50
- const subtitle = wrapper.find('.v-card-subtitle').text()
51
- expect(subtitle).toBe('Welcome back! Please enter your details')
52
- })
53
-
54
- it('renders with the correct structure', () => {
55
- expect(wrapper.element).toMatchSnapshot()
56
- })
57
-
58
- it('has the correct CSS class for the login card', () => {
59
- const loginCard = wrapper.find('.login-card')
60
- expect(loginCard.exists()).toBe(true)
61
- expect(loginCard.classes()).toContain('login-card')
62
- expect(loginCard.attributes('style')).toContain('border-radius: 10px')
63
- })
64
- })
@@ -1,65 +0,0 @@
1
- <template>
2
- <v-row
3
- class="position-relative"
4
- no-gutters
5
- >
6
- <v-col
7
- cols="12"
8
- lg="12"
9
- >
10
- <v-container>
11
- <div
12
- class="d-flex align-center"
13
- style="min-height: calc(100vh - 148px)"
14
- >
15
- <v-row
16
- justify="center"
17
- class="align-content-center"
18
- >
19
- <div class="pt-6 pl-6 d-flex flex-column align-center">
20
- <Logo />
21
-
22
- <v-toolbar-title class="text-uppercase text-red">
23
- <strong> FDM&nbsp; </strong>
24
- <strong> Monster </strong>
25
- </v-toolbar-title>
26
-
27
- <v-toolbar-title class="mt-lg-6 mt-sm-5 mb-md-5">
28
- Login to your account
29
- </v-toolbar-title>
30
-
31
- <v-card-subtitle class="text-grey mb-md-5">
32
- Welcome back! Please enter your details
33
- </v-card-subtitle>
34
- </div>
35
-
36
- <v-col
37
- cols="12"
38
- md="12"
39
- >
40
- <LoginForm class="login-card" />
41
- </v-col>
42
- </v-row>
43
- </div>
44
- </v-container>
45
- </v-col>
46
- </v-row>
47
- </template>
48
-
49
- <script lang="ts" setup>
50
- import LoginForm from './LoginForm.vue'
51
- </script>
52
-
53
- <style lang="scss">
54
- .login-card {
55
- max-width: 475px;
56
- margin: 0 auto;
57
- }
58
-
59
- .blur-logo {
60
- position: absolute;
61
- filter: blur(18px);
62
- bottom: 0;
63
- transform: inherit;
64
- }
65
- </style>
@@ -1,13 +0,0 @@
1
- <template>
2
- <v-img
3
- :src="imgUrl"
4
- class="shrink mr-1 pt-3 ml-1"
5
- contain
6
- style="opacity: 0.85"
7
- width="150"
8
- />
9
- </template>
10
-
11
- <script lang="ts" setup>
12
- import imgUrl from '@/assets/logo.png'
13
- </script>
@@ -1,109 +0,0 @@
1
- <template>
2
- <v-container
3
- fill-height
4
- fluid
5
- >
6
- <v-app-bar color="primary">
7
- <v-toolbar-title class="text-uppercase text-white">
8
- <span class="font-weight-light"> FDM </span>
9
- <strong> Monster </strong>
10
- </v-toolbar-title>
11
- </v-app-bar>
12
-
13
- <img
14
- alt="FDM Monster Background"
15
- class="grid-bg-img align-content-center"
16
- src="/img/logo.svg"
17
- style="opacity: 0.06"
18
- />
19
-
20
- <v-layout
21
- align-center
22
- column
23
- justify-center
24
- >
25
- <v-card
26
- class="flex align-center justify-center pa-lg-16 pa-sm-10"
27
- style="width: 80%"
28
- >
29
- <v-card-title>
30
- <v-icon
31
- class="mr-4"
32
- size="50"
33
- >
34
- lock
35
- </v-icon>
36
- <h3>Permission Denied</h3>
37
- </v-card-title>
38
- <v-card-subtitle class="mt-1">
39
- You do not have permission to access a specific resource on this page.
40
- </v-card-subtitle>
41
-
42
- <v-card-text v-if="permissionProblems">
43
- <div v-if="permissionProblems.page">
44
- Page:
45
- <strong>
46
- {{ permissionProblems?.page }}
47
- </strong>
48
- </div>
49
- <div v-if="permissionProblems.permissions">
50
- Required permission(s):
51
- <strong
52
- v-for="perm of permissionProblems.permissions"
53
- :key="perm"
54
- >
55
- {{ perm }}
56
- </strong>
57
- </div>
58
- <div v-if="permissionProblems.roles">
59
- Usable roles:
60
- <strong>
61
- {{ permissionProblems.roles?.join(', ') }}
62
- </strong>
63
- </div>
64
- <div v-if="permissionProblems.url">
65
- Problematic API path:
66
- <strong>
67
- {{ permissionProblems.url }}
68
- </strong>
69
- </div>
70
- <div v-if="permissionProblems.error">
71
- Error:
72
- <strong>
73
- {{ permissionProblems.error }}
74
- </strong>
75
- </div>
76
- </v-card-text>
77
- <v-card-actions class="mt-6">
78
- <v-btn
79
- class="align-center"
80
- color="primary"
81
- to="/"
82
- variant="elevated"
83
- >
84
- <v-icon class="mr-2">home</v-icon>
85
- Go home
86
- </v-btn>
87
- </v-card-actions>
88
- </v-card>
89
- </v-layout>
90
- </v-container>
91
- </template>
92
- <script lang="ts" setup>
93
- import { computed } from 'vue'
94
- import { useRoute } from 'vue-router'
95
-
96
- const route = useRoute()
97
-
98
- interface PermissionDeniedQuery {
99
- roles: string[]
100
- permissions?: string[]
101
- url?: string
102
- page?: string
103
- error?: string
104
- }
105
-
106
- const permissionProblems = computed(() => {
107
- return route.query as any as PermissionDeniedQuery
108
- })
109
- </script>
@@ -1,207 +0,0 @@
1
- <template>
2
- <v-container
3
- fill-height
4
- fluid
5
- >
6
- <v-layout
7
- align-content-center
8
- justify-center
9
- >
10
- <v-flex
11
- class="d-flex flex-column align-content-center"
12
- md4
13
- sm8
14
- style="max-width: 450px; margin-top: 10%"
15
- xs12
16
- >
17
- <div class="d-flex flex-column align-center">
18
- <v-img
19
- :src="require('@/assets/logo.png')"
20
- class="shrink mr-1 pt-3 ml-1"
21
- contain
22
- style="opacity: 0.85"
23
- width="150"
24
- />
25
-
26
- <v-toolbar-title class="text-uppercase text-red">
27
- <strong> FDM&nbsp; </strong>
28
- <strong> Monster </strong>
29
- </v-toolbar-title>
30
-
31
- <v-toolbar-title class="mt-lg-6 mt-sm-5">
32
- Register new account
33
- </v-toolbar-title>
34
- <v-card-subtitle class="text-grey">
35
- Welcome! Please register your guest account
36
- </v-card-subtitle>
37
- </div>
38
-
39
- <v-card
40
- class="elevation-4 pa-4"
41
- style="border-radius: 10px"
42
- >
43
- <v-card-text>
44
- <v-form>
45
- <label> Username </label>
46
- <v-text-field
47
- v-model="username"
48
- :rules="[
49
- (v) => !!v || 'Username is required',
50
- (v) =>
51
- (v?.length ?? 0) >= 3 ||
52
- 'Username must be of length 3 or greater',
53
- (v) =>
54
- !v.toLowerCase().includes('admin') ||
55
- 'Username may not contain the word admin',
56
- (v) =>
57
- !v.toLowerCase().includes('root') ||
58
- 'Username may not contain the word root',
59
- (v) =>
60
- !(v.toLowerCase() === 'demo') ||
61
- 'Username may not equal the word demo'
62
- ]"
63
- autofocus
64
- name="login"
65
- label="Username"
66
- prepend-icon="person"
67
- type="text"
68
- />
69
- <v-text-field
70
- id="password"
71
- v-model="password"
72
- :append-icon="showPassword ? 'visibility' : 'visibility_off'"
73
- :type="showPassword ? 'text' : 'password'"
74
- label="Password"
75
- name="password"
76
- :rules="[
77
- (v) => !!v || 'Password is required',
78
- (v) =>
79
- (!!v && v?.length >= 8) ||
80
- 'Password must be of length 8 or greater'
81
- ]"
82
- password
83
- prepend-icon="lock"
84
- @click:append="showPassword = !showPassword"
85
- />
86
- <v-text-field
87
- id="password"
88
- v-model="password2"
89
- :append-icon="showPassword2 ? 'visibility' : 'visibility_off'"
90
- :type="showPassword2 ? 'text' : 'password'"
91
- :rules="[
92
- (v) => !!v || 'Repeated password is required',
93
- (v) => v === password || 'Passwords are not equal'
94
- ]"
95
- label="Repeated Password"
96
- name="password"
97
- password
98
- prepend-icon="lock"
99
- @click:append="showPassword2 = !showPassword2"
100
- @keyup.enter="formIsDisabled || registerAccount()"
101
- />
102
- <v-alert
103
- v-if="errorMessage"
104
- class="mt-6"
105
- color="error"
106
- density="compact"
107
- variant="outlined"
108
- >
109
- {{ errorMessage }}
110
- </v-alert>
111
- </v-form>
112
- </v-card-text>
113
- <v-card-actions>
114
- <v-btn
115
- :loading="loading"
116
- class="pa-4"
117
- color="primary"
118
- size="large"
119
- style="width: 100%"
120
- @click="registerAccount()"
121
- >
122
- Register account
123
- </v-btn>
124
- </v-card-actions>
125
- <v-card-actions>
126
- <v-btn
127
- style="width: 100%"
128
- class="pa-4"
129
- size="large"
130
- @click="gotoLogin()"
131
- >
132
- <v-icon class="mr-2">arrow_left</v-icon>Back to Login
133
- </v-btn>
134
- </v-card-actions>
135
- </v-card>
136
- </v-flex>
137
- </v-layout>
138
- </v-container>
139
- </template>
140
- <script lang="ts" setup>
141
- import { AxiosError } from 'axios'
142
- import { computed, onMounted, ref } from 'vue'
143
- import { useAuthStore } from '@/store/auth.store'
144
- import { useRouter } from 'vue-router'
145
- import { useSnackbar } from '@/shared/snackbar.composable'
146
- import { AuthService } from '@/backend/auth.service'
147
- import { RouteNames } from '@/router/route-names'
148
-
149
- const authStore = useAuthStore()
150
- const router = useRouter()
151
- const errorMessage = ref('')
152
- const username = ref('')
153
- const showPassword = ref(false)
154
- const showPassword2 = ref(false)
155
- const password = ref('')
156
- const password2 = ref('')
157
- const loading = ref(false)
158
- const snackbar = useSnackbar()
159
-
160
- async function gotoLogin() {
161
- return await router.push({ name: RouteNames.Login })
162
- }
163
-
164
- const formIsDisabled = computed(() => {
165
- return (
166
- (username.value ?? '')?.length < 3 ||
167
- (password.value ?? '').length < 3 ||
168
- password.value != password2.value
169
- )
170
- })
171
-
172
- onMounted(async () => {
173
- await authStore.logout()
174
- await authStore.checkAuthenticationRequirements()
175
- if (!authStore.registration) {
176
- snackbar.info('Registration is disabled, please contact your administrator')
177
- await router.push({
178
- name: RouteNames.Login
179
- })
180
- }
181
- })
182
-
183
- async function registerAccount() {
184
- try {
185
- loading.value = true
186
- await AuthService.registerAccount(username.value, password.value)
187
- loading.value = false
188
- } catch (e) {
189
- loading.value = false
190
- if ((e as AxiosError)?.response?.status === 401) {
191
- errorMessage.value = 'Invalid credentials'
192
- return
193
- }
194
-
195
- snackbar.openErrorMessage({
196
- title: 'Error logging in',
197
- subtitle: 'Please test your connection and try again.'
198
- })
199
-
200
- return
201
- }
202
- errorMessage.value = ''
203
-
204
- snackbar.info('Account created, please login')
205
- await gotoLogin()
206
- }
207
- </script>
@@ -1,17 +0,0 @@
1
- <template>
2
- <v-container
3
- fill-height
4
- fluid
5
- >
6
- <v-layout
7
- align-center
8
- justify-center
9
- >
10
- <RegistrationForm />
11
- </v-layout>
12
- </v-container>
13
- </template>
14
-
15
- <script lang="ts" setup>
16
- import RegistrationForm from '@/components/Login/RegistrationForm.vue'
17
- </script>