@fdm-monster/client-next 0.0.1 → 0.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 (198) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/dist/assets/MaterialIcons-Regular-BjXOXp5c.eot +0 -0
  3. package/dist/assets/MaterialIcons-Regular-DEUTIz1o.ttf +0 -0
  4. package/dist/assets/MaterialIcons-Regular-DOtZ65Va.woff2 +0 -0
  5. package/dist/assets/MaterialIcons-Regular-FsbMSDLx.woff +0 -0
  6. package/dist/assets/index-CHzfWKPO.css +5 -0
  7. package/dist/assets/index-CnWtkGvw.js +90 -0
  8. package/dist/assets/index-CnWtkGvw.js.map +1 -0
  9. package/dist/favicon.ico +0 -0
  10. package/dist/img/DavidZwart.jpg +0 -0
  11. package/dist/img/OIG.JYDC2RaWdz7g9.jpg +0 -0
  12. package/dist/img/OIG.jpg +0 -0
  13. package/dist/img/icons/android-chrome-256x256.png +0 -0
  14. package/dist/img/icons/android-chrome-384x384.png +0 -0
  15. package/dist/img/icons/android-chrome-512x512.png +0 -0
  16. package/dist/img/icons/favicon.svg +1 -0
  17. package/dist/img/logo.png +0 -0
  18. package/dist/img/logo.svg +1 -0
  19. package/dist/img/manifest.webmanifest +33 -0
  20. package/dist/img/octoprint-tentacle.svg +144 -0
  21. package/dist/img/thumbail_unknown.jpg +0 -0
  22. package/dist/img/vbanner.jpg +0 -0
  23. package/dist/index.html +24 -0
  24. package/dist/robots.txt +2 -0
  25. package/package.json +1 -1
  26. package/.all-contributorsrc +0 -57
  27. package/.editorconfig +0 -5
  28. package/.eslintrc.js +0 -126
  29. package/.github/FUNDING.yml +0 -3
  30. package/.github/workflows/release-client.yml +0 -94
  31. package/.github/workflows/vue-publish.yml +0 -26
  32. package/.prettierignore +0 -15
  33. package/.whitesource +0 -12
  34. package/renovate.json +0 -30
  35. package/src/App.vue +0 -60
  36. package/src/AppLoader.vue +0 -383
  37. package/src/assets/adjectives.json +0 -1468
  38. package/src/assets/logo.svg +0 -6
  39. package/src/assets/nouns.json +0 -4309
  40. package/src/auto-imports.d.ts +0 -139
  41. package/src/backend/app.service.ts +0 -39
  42. package/src/backend/auth.service.ts +0 -56
  43. package/src/backend/base.service.ts +0 -57
  44. package/src/backend/batch.service.ts +0 -37
  45. package/src/backend/camera-stream.service.ts +0 -33
  46. package/src/backend/custom-gcode.service.ts +0 -11
  47. package/src/backend/dto/octoprint-settings.dto.ts +0 -168
  48. package/src/backend/first-time-setup.service.ts +0 -17
  49. package/src/backend/floor.service.ts +0 -84
  50. package/src/backend/index.ts +0 -4
  51. package/src/backend/print-completions.service.ts +0 -11
  52. package/src/backend/printer-file.service.ts +0 -91
  53. package/src/backend/printer-group.service.ts +0 -62
  54. package/src/backend/printer-job.service.ts +0 -20
  55. package/src/backend/printer-settings.service.ts +0 -28
  56. package/src/backend/printers.service.ts +0 -136
  57. package/src/backend/server-private.service.ts +0 -55
  58. package/src/backend/server.api.ts +0 -132
  59. package/src/backend/settings.service.ts +0 -85
  60. package/src/backend/user.service.ts +0 -51
  61. package/src/components/AboutHelp/AboutView.vue +0 -164
  62. package/src/components/CameraGrid/CameraGridView.vue +0 -111
  63. package/src/components/FirstTimeSetup/FirstTimeSetupView.vue +0 -354
  64. package/src/components/Generic/Actions/PrinterConnectionAction.vue +0 -56
  65. package/src/components/Generic/Actions/PrinterCreateAction.vue +0 -22
  66. package/src/components/Generic/Actions/PrinterDeleteAction.vue +0 -29
  67. package/src/components/Generic/Actions/PrinterQuickStopAction.vue +0 -35
  68. package/src/components/Generic/Actions/PrinterSettingsAction.vue +0 -35
  69. package/src/components/Generic/Actions/PrinterUrlAction.vue +0 -24
  70. package/src/components/Generic/Actions/RefreshFilesAction.vue +0 -50
  71. package/src/components/Generic/Actions/SyncPrinterNameAction.vue +0 -36
  72. package/src/components/Generic/Dialogs/AddOrUpdateCameraStreamDialog.vue +0 -131
  73. package/src/components/Generic/Dialogs/AddOrUpdateFloorDialog.vue +0 -141
  74. package/src/components/Generic/Dialogs/AddOrUpdatePrinterDialog.vue +0 -303
  75. package/src/components/Generic/Dialogs/BaseDialog.vue +0 -81
  76. package/src/components/Generic/Dialogs/BatchJsonCreateDialog.vue +0 -109
  77. package/src/components/Generic/Dialogs/BatchReprintDialog.vue +0 -190
  78. package/src/components/Generic/Dialogs/PrinterChecksPanel.vue +0 -37
  79. package/src/components/Generic/Dialogs/PrinterControlDialog.vue +0 -202
  80. package/src/components/Generic/Dialogs/PrinterMaintenanceDialog.vue +0 -130
  81. package/src/components/Generic/Dialogs/YamlImportExportDialog.vue +0 -186
  82. package/src/components/Generic/Dialogs/dialog.constants.ts +0 -19
  83. package/src/components/Generic/FileExplorerSideNav.vue +0 -734
  84. package/src/components/Generic/Loaders/GridLoader.vue +0 -68
  85. package/src/components/Generic/NavigationDrawer.vue +0 -69
  86. package/src/components/Generic/PrintJobsMenu.vue +0 -148
  87. package/src/components/Generic/Snackbars/AppErrorSnackbar.vue +0 -64
  88. package/src/components/Generic/Snackbars/AppInfoSnackbar.vue +0 -63
  89. package/src/components/Generic/Snackbars/AppProgressSnackbar.vue +0 -158
  90. package/src/components/Generic/Vuetify/TooltipButton.vue +0 -47
  91. package/src/components/HelpOverlay/HelpOverlay.vue +0 -57
  92. package/src/components/Login/LoginForm.vue +0 -206
  93. package/src/components/Login/LoginView.spec.ts +0 -64
  94. package/src/components/Login/LoginView.vue +0 -65
  95. package/src/components/Login/Logo.vue +0 -13
  96. package/src/components/Login/PermissionDenied.vue +0 -109
  97. package/src/components/Login/RegistrationForm.vue +0 -207
  98. package/src/components/Login/RegistrationView.vue +0 -17
  99. package/src/components/Login/__snapshots__/LoginView.spec.ts.snap +0 -1051
  100. package/src/components/NotFound/NotFoundView.vue +0 -39
  101. package/src/components/PrintStatistics/PrintStatistics.vue +0 -168
  102. package/src/components/PrintStatistics/PrintStatisticsView.vue +0 -15
  103. package/src/components/PrinterGrid/HomeToolbar.vue +0 -90
  104. package/src/components/PrinterGrid/PrinterGrid.vue +0 -164
  105. package/src/components/PrinterGrid/PrinterGridTile.vue +0 -438
  106. package/src/components/PrinterGrid/PrinterGridView.vue +0 -210
  107. package/src/components/PrinterList/FileControlList.vue +0 -40
  108. package/src/components/PrinterList/PrinterDetails.vue +0 -91
  109. package/src/components/PrinterList/PrintersView.vue +0 -492
  110. package/src/components/Settings/AccountSettings.vue +0 -163
  111. package/src/components/Settings/DiagnosticsSettings.vue +0 -137
  112. package/src/components/Settings/EmergencyCommands.vue +0 -265
  113. package/src/components/Settings/FloorSettings.vue +0 -276
  114. package/src/components/Settings/GridSettings.vue +0 -127
  115. package/src/components/Settings/OctoPrintSettings.vue +0 -188
  116. package/src/components/Settings/ServerProtectionSettings.vue +0 -370
  117. package/src/components/Settings/SettingsView.vue +0 -73
  118. package/src/components/Settings/SoftwareUpgradeSettings.vue +0 -297
  119. package/src/components/Settings/UserManagementSettings.vue +0 -257
  120. package/src/components/TopBar.vue +0 -147
  121. package/src/components.d.ts +0 -70
  122. package/src/directives/file-upload.directive.ts +0 -117
  123. package/src/directives/printer-drop-position.directive.ts +0 -92
  124. package/src/env.d.ts +0 -6
  125. package/src/main.ts +0 -76
  126. package/src/models/batch/reprint.dto.ts +0 -79
  127. package/src/models/batch.model.ts +0 -11
  128. package/src/models/camera-streams/camera-stream.ts +0 -19
  129. package/src/models/floors/floor.model.ts +0 -30
  130. package/src/models/octoprint/connection-options.model.ts +0 -8
  131. package/src/models/plugins/firmware-updates/prusa-firmware-release.model.ts +0 -57
  132. package/src/models/print-completions/print-completions.model.ts +0 -49
  133. package/src/models/printers/crud/create-printer.model.ts +0 -26
  134. package/src/models/printers/file-upload-commands.model.ts +0 -4
  135. package/src/models/printers/gcode/gcode-analysis.model.ts +0 -30
  136. package/src/models/printers/printer-current-job.model.ts +0 -90
  137. package/src/models/printers/printer-file.model.ts +0 -48
  138. package/src/models/printers/printer.model.ts +0 -18
  139. package/src/models/server/client-releases.model.ts +0 -27
  140. package/src/models/server/export-yaml.model.ts +0 -11
  141. package/src/models/server/features.model.ts +0 -37
  142. package/src/models/server/github-rate-limit.model.ts +0 -21
  143. package/src/models/server/version.model.ts +0 -14
  144. package/src/models/settings/printer-file-clean-settings.model.ts +0 -5
  145. package/src/models/settings/server-settings.dto.ts +0 -19
  146. package/src/models/settings/settings.model.ts +0 -57
  147. package/src/models/socketio-messages/socketio-message.model.ts +0 -53
  148. package/src/models/uploads/queued-upload.model.ts +0 -12
  149. package/src/models/user.model.ts +0 -15
  150. package/src/plugins/README.md +0 -3
  151. package/src/plugins/index.ts +0 -17
  152. package/src/plugins/vuetify.ts +0 -53
  153. package/src/router/index.ts +0 -192
  154. package/src/router/route-names.ts +0 -14
  155. package/src/router/utils.ts +0 -23
  156. package/src/shared/alert.events.ts +0 -14
  157. package/src/shared/app.constants.ts +0 -23
  158. package/src/shared/auth.constants.ts +0 -34
  159. package/src/shared/dialog.composable.ts +0 -41
  160. package/src/shared/drag.constants.ts +0 -19
  161. package/src/shared/experimental.constants.ts +0 -1
  162. package/src/shared/http-client.ts +0 -162
  163. package/src/shared/noun-adjectives.data.ts +0 -24
  164. package/src/shared/printer-grid.constants.ts +0 -5
  165. package/src/shared/printer-state.constants.ts +0 -194
  166. package/src/shared/snackbar.composable.ts +0 -66
  167. package/src/shared/socketio.service.ts +0 -104
  168. package/src/store/auth.store.ts +0 -255
  169. package/src/store/connection.store.ts +0 -66
  170. package/src/store/dialog.store.ts +0 -114
  171. package/src/store/features.store.ts +0 -57
  172. package/src/store/floor.store.ts +0 -173
  173. package/src/store/grid.store.ts +0 -10
  174. package/src/store/index.ts +0 -4
  175. package/src/store/printer-state.store.ts +0 -246
  176. package/src/store/printer.store.ts +0 -236
  177. package/src/store/profile.store.ts +0 -25
  178. package/src/store/settings.store.ts +0 -64
  179. package/src/store/test-printer.store.ts +0 -70
  180. package/src/store/uploads.store.ts +0 -75
  181. package/src/styles/README.md +0 -3
  182. package/src/styles/settings.scss +0 -10
  183. package/src/types/global.d.ts +0 -15
  184. package/src/utils/array.utils.ts +0 -15
  185. package/src/utils/date.utils.ts +0 -5
  186. package/src/utils/download-file.util.ts +0 -25
  187. package/src/utils/error.utils.ts +0 -3
  188. package/src/utils/file-size.util.ts +0 -11
  189. package/src/utils/id.type.ts +0 -1
  190. package/src/utils/sentry.util.ts +0 -8
  191. package/src/utils/test.util.ts +0 -30
  192. package/src/utils/time.utils.ts +0 -2
  193. package/src/utils/uploads-state.utils.ts +0 -58
  194. package/src/utils/validation.utils.ts +0 -14
  195. package/src/vite-env.d.ts +0 -7
  196. package/test/setup-axios-mock.ts +0 -15
  197. /package/{src/assets/logo.png → dist/assets/logo-CJVdjy51.png} +0 -0
  198. /package/{src/assets → dist/img/icons}/android-chrome-192x192.png +0 -0
@@ -1,194 +0,0 @@
1
- import {
2
- PrinterStateDto,
3
- SocketState
4
- } from '@/models/socketio-messages/socketio-message.model'
5
- import { PrinterDto } from '@/models/printers/printer.model'
6
- import { useSettingsStore } from '@/store/settings.store'
7
-
8
- const COLOR = {
9
- danger: 'danger',
10
- dark: 'dark',
11
- secondary: 'secondary',
12
- success: 'success'
13
- } as const
14
-
15
- const RGB = {
16
- DarkBlue: '#050c2e',
17
- Black: '#000000',
18
- DarkGray: '#262626',
19
- LightBrown: '#583c0e',
20
- Brown: '#580e47',
21
- Red: '#2e0905'
22
- } as const
23
-
24
- const LABEL = {
25
- Disabled: 'Disabled',
26
- Maintenance: 'Maintenance',
27
- Offline: 'Offline',
28
- Finding: 'Finding',
29
- Disconnected: 'Disconnected',
30
- Error: 'Error',
31
- Paused: 'Paused',
32
- Operational: 'Operational',
33
- Printing: 'Printing'
34
- } as const
35
-
36
- export function interpretStates(
37
- printer: PrinterDto,
38
- socketState: SocketState,
39
- printerState: PrinterStateDto
40
- ) {
41
- const settingsStore = useSettingsStore()
42
- const debugPrinterInterpretState =
43
- settingsStore.frontendDebugSettings.showInterpretedPrinterState
44
- const state = {}
45
-
46
- // Disabled/maintenance printers
47
- if (!printer.enabled) {
48
- if (printer.disabledReason?.length) {
49
- return {
50
- ...state,
51
- color: COLOR.danger,
52
- rgb: RGB.Black,
53
- text: LABEL.Maintenance
54
- }
55
- }
56
- return {
57
- ...state,
58
- color: COLOR.secondary,
59
- rgb: RGB.DarkBlue,
60
- text: LABEL.Disabled
61
- }
62
- }
63
-
64
- // Basic necessity to parse API/Websocket states
65
- const responding = socketState?.api === 'responding'
66
- const authFail = socketState?.api === 'authFail'
67
- if (!responding || !socketState) {
68
- const noResponse = socketState?.api === 'noResponse'
69
- return {
70
- ...state,
71
- color: COLOR.secondary,
72
- rgb: RGB.Red,
73
- text: authFail
74
- ? 'API key wrong'
75
- : noResponse
76
- ? 'API unreachable'
77
- : socketState?.api || '-'
78
- }
79
- }
80
-
81
- // First level: API
82
- // Backend has concluded that things are not retryable
83
- if (!responding) {
84
- return {
85
- ...state,
86
- color: COLOR.danger,
87
- rgb: RGB.Red,
88
- text: authFail ? 'API key wrong' : 'No API connection'
89
- }
90
- }
91
-
92
- // Second level: socket state
93
- const socketAuthenticated = socketState.socket === 'authenticated'
94
- const socketAuthing = socketState.socket === 'authenticating'
95
- const currentState = printerState?.current?.payload?.state
96
-
97
- // History might be way outdated
98
- // if (!currentState) {
99
- // currentState = printerState?.history?.payload?.state;
100
- // }
101
-
102
- const flags = currentState?.flags
103
- if (!socketAuthenticated || !flags) {
104
- const s = socketAuthenticated ? 1 : 0
105
- const sa = socketAuthing ? 1 : 0
106
- const p = printerState ? 1 : 0
107
- if (debugPrinterInterpretState)
108
- console.debug(
109
- `Socket opened ${s}, socketAuthing ${sa} printerState ${p},
110
- currentState: ${currentState}, FLAGS ${flags}`
111
- )
112
- return {
113
- ...state,
114
- color: COLOR.danger,
115
- rgb: RGB.Red,
116
- // TODO this should not result in S/SA/P label, but in a more descriptive label
117
- text: !printerState ? 'No USB' : `S${s} SA${sa} | P${p}`
118
- }
119
- }
120
-
121
- if (!flags) {
122
- console.error('No flags', flags)
123
- return
124
- }
125
-
126
- if (flags.error || flags.closedOrError) {
127
- return {
128
- ...state,
129
- color: COLOR.danger,
130
- rgb: RGB.Red,
131
- text:
132
- currentState.text?.replace('Offline', 'Disconnected') || LABEL.Error,
133
- description: currentState.error
134
- }
135
- } else if (flags.paused || flags.pausing) {
136
- return {
137
- ...state,
138
- color: COLOR.success,
139
- rgb: RGB.Brown,
140
- text: LABEL.Paused
141
- }
142
- } else if (flags.printing) {
143
- return {
144
- ...state,
145
- color: COLOR.success,
146
- rgb: RGB.LightBrown,
147
- text: LABEL.Printing
148
- }
149
- } else {
150
- return {
151
- ...state,
152
- color: COLOR.dark,
153
- rgb: RGB.DarkGray,
154
- text: LABEL.Operational,
155
- description: currentState.error
156
- }
157
- }
158
- }
159
-
160
- const toCurrentState = (printerState: PrinterStateDto) =>
161
- printerState?.current?.payload?.state
162
-
163
- export const isPrinterPrinting = (printerState: PrinterStateDto) =>
164
- toCurrentState(printerState)?.flags.printing
165
-
166
- export const isPrinterPaused = (printerState: PrinterStateDto) =>
167
- toCurrentState(printerState)?.flags?.paused ||
168
- toCurrentState(printerState)?.flags?.pausing
169
-
170
- export const isPrinterDisconnected = (
171
- printer: PrinterDto,
172
- printerState: PrinterStateDto
173
- ) =>
174
- (!isPrinterInMaintenance(printer) &&
175
- printer?.enabled &&
176
- !toCurrentState(printerState)?.flags.operational) ||
177
- toCurrentState(printerState)?.flags.error ||
178
- toCurrentState(printerState)?.flags.closedOrError
179
-
180
- export const isPrinterDisabled = (printer: PrinterDto) =>
181
- !isPrinterInMaintenance(printer) && !printer?.enabled
182
-
183
- export const isPrinterInMaintenance = (printer?: PrinterDto) =>
184
- !printer?.enabled && printer?.disabledReason?.length
185
-
186
- export const isPrinterIdling = (
187
- printer: PrinterDto,
188
- printerState: PrinterStateDto
189
- ) =>
190
- toCurrentState(printerState)?.flags &&
191
- !toCurrentState(printerState)?.flags.printing &&
192
- toCurrentState(printerState)?.flags.operational &&
193
- !isPrinterDisabled(printer) &&
194
- !isPrinterInMaintenance(printer)
@@ -1,66 +0,0 @@
1
- import type { EventBusKey } from '@vueuse/core'
2
- import { useEventBus } from '@vueuse/core'
3
-
4
- export const progressMessageKey: EventBusKey<{ name: 'progress-message' }> =
5
- Symbol('Progress snackbar message event symbol')
6
- export const infoMessageKey: EventBusKey<{ name: 'info-message' }> = Symbol(
7
- 'Info snackbar message event symbol'
8
- )
9
- export const errorMessageKey: EventBusKey<{ name: 'error-message' }> = Symbol(
10
- 'Error snackbar message event symbol'
11
- )
12
-
13
- export interface InfoMessage {
14
- title: string
15
- subtitle?: string | null
16
- warning?: boolean
17
- timeout?: number
18
- }
19
-
20
- export interface ErrorMessage {
21
- title: string
22
- subtitle?: string | null
23
- timeout?: number
24
- // The idea is that the error can be revisited on a separate page/dialog
25
- // url?: string;
26
- }
27
-
28
- export interface ProgressMessage {
29
- key: string
30
- title: string
31
- value: number
32
- completed: boolean
33
- }
34
-
35
- export function useSnackbar() {
36
- const { emit: emitProgessMessage, on: onProgressMessage } =
37
- useEventBus<ProgressMessage>(progressMessageKey)
38
- const { emit: emitInfoMessage, on: onInfoMessage } =
39
- useEventBus<InfoMessage>(infoMessageKey)
40
- const { emit: emitErrorMessage, on: onErrorMessage } =
41
- useEventBus<ErrorMessage>(errorMessageKey)
42
-
43
- return {
44
- openProgressMessage: (
45
- key: string,
46
- title: string,
47
- value: number,
48
- completed: boolean
49
- ) =>
50
- emitProgessMessage({
51
- key,
52
- title,
53
- value,
54
- completed
55
- } as ProgressMessage),
56
- openInfoMessage: (data: InfoMessage) => emitInfoMessage(data),
57
- info: (title: string, subtitle?: string, timeout?: number) =>
58
- emitInfoMessage({ title, subtitle, timeout }),
59
- openErrorMessage: (errorData: ErrorMessage) => emitErrorMessage(errorData),
60
- error: (title: string, subtitle?: string) =>
61
- emitErrorMessage({ title, subtitle }),
62
- onProgressMessage,
63
- onInfoMessage,
64
- onErrorMessage
65
- }
66
- }
@@ -1,104 +0,0 @@
1
- import {
2
- PrinterStateDto,
3
- SocketIoUpdateMessage
4
- } from '@/models/socketio-messages/socketio-message.model'
5
- import { usePrinterStore } from '@/store/printer.store'
6
- import { useFloorStore } from '@/store/floor.store'
7
- import { usePrinterStateStore } from '@/store/printer-state.store'
8
- import { useTestPrinterStore } from '@/store/test-printer.store'
9
- import { useSnackbar } from './snackbar.composable'
10
- import { getBaseUri } from '@/shared/http-client'
11
- import { useAuthStore } from '@/store/auth.store'
12
- import { IdType } from '@/utils/id.type'
13
- import {
14
- appSocketIO,
15
- constructSocket,
16
- deconstructSocket,
17
- getSocketState,
18
- resetSocketConnection
19
- } from '@/store/connection.store'
20
-
21
- enum IO_MESSAGES {
22
- LegacyUpdate = 'legacy-update',
23
- TestPrinterState = 'test-printer-state',
24
- // CompletionEvent = "completion-event",
25
- HostState = 'host-state',
26
- ApiAccessibility = 'api-accessibility'
27
- }
28
-
29
- export class SocketIoService {
30
- private printerStore = usePrinterStore()
31
- private floorStore = useFloorStore()
32
- private printerStateStore = usePrinterStateStore()
33
- private testPrinterStore = useTestPrinterStore()
34
- private snackbar = useSnackbar()
35
-
36
- socketState() {
37
- return getSocketState()
38
- }
39
-
40
- async setupSocketConnection() {
41
- console.debug('Setting up socket.io client')
42
- const apiBase = await getBaseUri()
43
- const authStore = useAuthStore()
44
- authStore.loadTokens()
45
- constructSocket(
46
- apiBase,
47
- authStore.loginRequired ? authStore.token : undefined
48
- )
49
-
50
- appSocketIO?.on(IO_MESSAGES.LegacyUpdate, (data) =>
51
- this.onMessage(JSON.parse(data))
52
- )
53
- appSocketIO?.on(IO_MESSAGES.TestPrinterState, (data) => {
54
- this.testPrinterStore.saveEvent(data)
55
- console.log(data)
56
- })
57
- }
58
-
59
- disconnect() {
60
- deconstructSocket()
61
- }
62
-
63
- reconnect() {
64
- if (appSocketIO) {
65
- console.debug('Resetting socket.io client connection')
66
- resetSocketConnection()
67
- }
68
- }
69
-
70
- onMessage(message: SocketIoUpdateMessage) {
71
- if (
72
- message.trackedUploads.current?.length ||
73
- message.trackedUploads.failed?.length
74
- ) {
75
- console.debug('[SocketIO] trackedUploads message received')
76
- message.trackedUploads.current.forEach((u) => {
77
- this.snackbar.openProgressMessage(
78
- u.correlationToken,
79
- u.multerFile.originalname,
80
- (u.progress?.percent || 0) * 100,
81
- false
82
- )
83
- })
84
- }
85
-
86
- if (message.floors?.length) {
87
- this.floorStore.saveFloors(message.floors)
88
- }
89
-
90
- if (message.printers?.length) {
91
- this.printerStore.setPrinters(message.printers)
92
- }
93
-
94
- if (message.socketStates) {
95
- this.printerStateStore.setSocketStates(message.socketStates)
96
- }
97
-
98
- if (message.printerEvents) {
99
- this.printerStateStore.setPrinterEvents(
100
- message.printerEvents as Record<IdType, PrinterStateDto>
101
- )
102
- }
103
- }
104
- }
@@ -1,255 +0,0 @@
1
- import { defineStore } from 'pinia'
2
- import { useJwt } from '@vueuse/integrations/useJwt'
3
- import type { JwtPayload } from 'jwt-decode'
4
- import { AuthService, type Tokens } from '@/backend/auth.service'
5
- import { AxiosError, HttpStatusCode } from 'axios'
6
- import { WizardSettingsDto } from '@/models/settings/settings.model'
7
- import {
8
- AUTH_ERROR_REASON,
9
- convertAuthErrorReason
10
- } from '@/shared/auth.constants'
11
- import { useEventBus } from '@vueuse/core/index'
12
-
13
- export interface IClaims extends JwtPayload {
14
- name: string
15
- }
16
-
17
- export interface AuthState {
18
- isDemoMode: boolean | null
19
- loginRequired: boolean | null
20
- refreshToken: string | null
21
- registration: boolean | null
22
- token: string | null
23
- wizardState: WizardSettingsDto | null
24
- lastLogoutReason: string | null
25
- }
26
-
27
- export const useAuthStore = defineStore('auth', {
28
- state: (): AuthState => ({
29
- isDemoMode: null,
30
- token: null,
31
- refreshToken: null,
32
- loginRequired: null,
33
- registration: null,
34
- wizardState: null,
35
- lastLogoutReason: null
36
- }),
37
- actions: {
38
- async checkAuthenticationRequirements() {
39
- return await AuthService.getLoginRequired()
40
- .then((response) => {
41
- this.loginRequired = response.data.loginRequired
42
- this.wizardState = response.data.wizardState
43
- this.registration = response.data.registration
44
- this.isDemoMode = response.data.isDemoMode
45
- return {
46
- loginRequired: this.loginRequired,
47
- wizardState: this.wizardState,
48
- registration: this.registration
49
- }
50
- })
51
- .catch((e: AxiosError) => {
52
- console.error(
53
- 'authRequired: failed to check login required',
54
- e.response?.status
55
- )
56
- throw e
57
- })
58
- },
59
- async login(username: string, password: string): Promise<Tokens | null> {
60
- this.lastLogoutReason = null
61
- return await AuthService.postLogin(username, password)
62
- .then((response) => {
63
- this.setTokens(response.data.token, response.data.refreshToken)
64
- return response.data
65
- })
66
- .catch((e: AxiosError) => {
67
- console.error('login: failed to login', e.response?.status)
68
- throw e
69
- })
70
- },
71
- async logout(callServerLogout = false, reason?: string) {
72
- console.debug(`Logging out (calling server ${callServerLogout})`)
73
- if (reason) {
74
- this.lastLogoutReason = reason
75
- }
76
- if (callServerLogout && !!this.tokenClaims && !this.isLoginExpired) {
77
- try {
78
- await AuthService.logout()
79
- } catch (e) {
80
- console.error(
81
- 'Server could not process logout, but local logout was successful',
82
- e
83
- )
84
- }
85
- }
86
- this.setIdToken(undefined)
87
- this.setRefreshToken(undefined)
88
- },
89
- async verifyOrRefreshLoginOnceOrLogout() {
90
- try {
91
- await AuthService.verifyLogin()
92
- return { success: true }
93
- } catch (e1) {
94
- console.error(
95
- '[AuthStore.verifyOrRefreshLoginOnce]: failed to verify login',
96
- e1
97
- )
98
-
99
- const error = e1 as AxiosError
100
- if (
101
- !error.response ||
102
- error.response?.status !== HttpStatusCode.Unauthorized
103
- ) {
104
- // Ensure no request-retry is done, nor other error processing
105
- console.error(
106
- '[AuthStore.verifyOrRefreshLoginOnce]: unknown error',
107
- error.status
108
- )
109
- // This is meant to be caught by AppLoader, which know how to break the flow and extract the error data (body, url)
110
- throw e1
111
- }
112
-
113
- // Detect reasons for which we should not refresh, and handle the emitted event to change the UI page
114
- const { reasonCode, url } = this.extractSpecialReasonCode(
115
- e1 as AxiosError
116
- )
117
- if (reasonCode) {
118
- await this.logout(false, convertAuthErrorReason(reasonCode))
119
- console.error(
120
- `[AuthStore] 401 Unauthorized - emitting 'auth:${reasonCode}' with reason ${reasonCode}`
121
- )
122
- useEventBus(`auth:${reasonCode}`).emit({
123
- url,
124
- error: error.message,
125
- reasonCode
126
- })
127
- // The caller must abort their action, but avoid rerouting to login - special case
128
- return { success: false, handled: true }
129
- }
130
- if (!this.hasRefreshToken) {
131
- // The caller must abort their action, but may reroute to login
132
- return { success: false, handled: false }
133
- }
134
-
135
- // Try to refresh the token
136
- try {
137
- await this.refreshLoginToken()
138
- await AuthService.verifyLogin()
139
- } catch (e2: any | AxiosError) {
140
- // Failure at this point is handled ruthlessly
141
- const error = e2 as AxiosError
142
- if (error.response?.status === HttpStatusCode.Unauthorized) {
143
- await this.logout(false)
144
- console.error(
145
- '[AuthStore.verifyOrRefreshLoginOnce]: failed to refresh token',
146
- error.status
147
- )
148
- // Refresh was successful
149
- return { success: false, handled: false }
150
- } else {
151
- // Ensure no request-retry is done, nor other error processing
152
- throw e2
153
- }
154
- }
155
-
156
- // Refresh was successful
157
- return { success: true, handled: false }
158
- }
159
- },
160
- extractSpecialReasonCode(error: AxiosError) {
161
- // Detect reasons for which we should not retry
162
- // - AccountNotVerified the admin has not verified the account yet and this needs to be shown to the user
163
- // - PasswordChangeRequired the user needs to change their password
164
- const reasonCode: keyof typeof AUTH_ERROR_REASON = (
165
- error?.response?.data as any
166
- )?.reasonCode
167
- if (reasonCode) {
168
- console.error(
169
- '[AuthStore] 401 Unauthorized - Checking received reason code',
170
- reasonCode
171
- )
172
- }
173
- if (
174
- reasonCode &&
175
- (reasonCode === AUTH_ERROR_REASON.AccountNotVerified ||
176
- reasonCode === AUTH_ERROR_REASON.PasswordChangeRequired)
177
- ) {
178
- return { reasonCode, url: error?.config?.url }
179
- }
180
-
181
- return { reasonCode: null, url: null }
182
- },
183
- loadTokens() {
184
- this.token = localStorage.getItem('token')
185
- this.refreshToken = localStorage.getItem('refreshToken')
186
- },
187
- async refreshLoginToken() {
188
- if (!this.refreshToken) {
189
- throw new Error('refreshLoginToken: no refresh token')
190
- }
191
- return await AuthService.refreshLogin(this.refreshToken)
192
- .then((response) => {
193
- if (response?.data?.token) {
194
- this.setIdToken(response.data.token)
195
- }
196
-
197
- return true
198
- })
199
- .catch((e: AxiosError) => {
200
- if (e.response?.status == HttpStatusCode.Unauthorized) {
201
- this.setTokens(undefined, undefined)
202
- console.error(
203
- 'refreshLoginToken: authentication error, failed to refresh tokens',
204
- e.response?.status
205
- )
206
- } else {
207
- console.error(
208
- 'refreshLoginToken: unknown error, failed to refresh tokens',
209
- e.response?.status
210
- )
211
- }
212
- throw e
213
- })
214
- },
215
- setTokens(token?: string, refreshToken?: string) {
216
- this.setIdToken(token)
217
- this.setRefreshToken(refreshToken)
218
- },
219
- setIdToken(token?: string) {
220
- if (!token?.length) {
221
- localStorage.removeItem('token')
222
- } else {
223
- localStorage.setItem('token', token as string)
224
- this.token = token
225
- }
226
- },
227
- setRefreshToken(refreshToken?: string) {
228
- if (!refreshToken?.length) {
229
- localStorage.removeItem('refreshToken')
230
- } else {
231
- localStorage.setItem('refreshToken', refreshToken as string)
232
- this.refreshToken = refreshToken
233
- }
234
- }
235
- },
236
- getters: {
237
- hasRefreshToken(): boolean {
238
- return !!this.refreshToken
239
- },
240
- isLoginExpired(): boolean {
241
- const claims = this.tokenClaims
242
- if (!claims?.exp) return false
243
- return claims.exp < Date.now() / 1000
244
- },
245
- hasAuthToken() {
246
- return !!this.tokenClaims
247
- },
248
- tokenClaims(): IClaims | null {
249
- if (!this.token) return null
250
- const data = useJwt<IClaims>(this.token, { fallbackValue: null })
251
- if (!data) return null
252
- return data.payload.value
253
- }
254
- }
255
- })
@@ -1,66 +0,0 @@
1
- import { io, Socket } from 'socket.io-client'
2
- import { reactive } from 'vue'
3
-
4
- export let appSocketIO: Socket | null = null
5
-
6
- export const socketState = reactive({
7
- connected: false,
8
- setup: false,
9
- id: ''
10
- })
11
-
12
- export function constructSocket(apiBase: string, token?: string | null) {
13
- if (socketState.setup) {
14
- throw new Error('Socket already set up')
15
- }
16
- socketState.setup = false
17
- appSocketIO = io(apiBase, {
18
- auth: token?.length ? { token } : undefined
19
- })
20
- socketState.setup = true
21
-
22
- appSocketIO.on('connect', () => {
23
- socketState.id = appSocketIO!.id || ''
24
- socketState.connected = true
25
- })
26
-
27
- appSocketIO.on('disconnect', () => {
28
- socketState.id = ''
29
- socketState.connected = false
30
- })
31
- }
32
-
33
- export function resetSocketConnection() {
34
- socketState.connected = false
35
- appSocketIO?.close()
36
- appSocketIO?.open()
37
- }
38
-
39
- export function deconstructSocket() {
40
- if (appSocketIO) {
41
- appSocketIO.close()
42
- }
43
- appSocketIO = null
44
- socketState.setup = false
45
- socketState.connected = false
46
- socketState.id = ''
47
- }
48
-
49
- export function getSocketState() {
50
- if (!appSocketIO) {
51
- console.warn('Socket not set-up')
52
- return {
53
- setup: false
54
- }
55
- }
56
-
57
- const state = {
58
- setup: true,
59
- active: appSocketIO.active,
60
- connected: appSocketIO.connected,
61
- id: appSocketIO.id,
62
- recovered: appSocketIO.recovered
63
- }
64
- console.warn(state)
65
- return state
66
- }