@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.
- package/.yarn/install-state.gz +0 -0
- package/RELEASE_NOTES.MD +28 -1
- package/dist/assets/MaterialIcons-Regular-BjXOXp5c.eot +0 -0
- package/dist/assets/MaterialIcons-Regular-DEUTIz1o.ttf +0 -0
- package/dist/assets/MaterialIcons-Regular-DOtZ65Va.woff2 +0 -0
- package/dist/assets/MaterialIcons-Regular-FsbMSDLx.woff +0 -0
- package/dist/assets/index-CHzfWKPO.css +5 -0
- package/dist/assets/index-WVqTlgq7.js +90 -0
- package/dist/assets/index-WVqTlgq7.js.map +1 -0
- package/dist/favicon.ico +0 -0
- package/dist/img/DavidZwart.jpg +0 -0
- package/dist/img/OIG.JYDC2RaWdz7g9.jpg +0 -0
- package/dist/img/OIG.jpg +0 -0
- package/dist/img/icons/android-chrome-256x256.png +0 -0
- package/dist/img/icons/android-chrome-384x384.png +0 -0
- package/dist/img/icons/android-chrome-512x512.png +0 -0
- package/dist/img/icons/favicon.svg +1 -0
- package/dist/img/logo.png +0 -0
- package/dist/img/logo.svg +1 -0
- package/dist/img/manifest.webmanifest +33 -0
- package/dist/img/octoprint-tentacle.svg +144 -0
- package/dist/img/thumbail_unknown.jpg +0 -0
- package/dist/img/vbanner.jpg +0 -0
- package/dist/index.html +24 -0
- package/dist/robots.txt +2 -0
- package/package.json +1 -1
- package/.all-contributorsrc +0 -57
- package/.editorconfig +0 -5
- package/.eslintrc.js +0 -126
- package/.github/FUNDING.yml +0 -3
- package/.github/workflows/release-client.yml +0 -94
- package/.github/workflows/vue-publish.yml +0 -26
- package/.prettierignore +0 -15
- package/.whitesource +0 -12
- package/renovate.json +0 -30
- package/src/App.vue +0 -60
- package/src/AppLoader.vue +0 -383
- package/src/assets/adjectives.json +0 -1468
- package/src/assets/logo.svg +0 -6
- package/src/assets/nouns.json +0 -4309
- package/src/auto-imports.d.ts +0 -139
- package/src/backend/app.service.ts +0 -39
- package/src/backend/auth.service.ts +0 -56
- package/src/backend/base.service.ts +0 -57
- package/src/backend/batch.service.ts +0 -37
- package/src/backend/camera-stream.service.ts +0 -33
- package/src/backend/custom-gcode.service.ts +0 -11
- package/src/backend/dto/octoprint-settings.dto.ts +0 -168
- package/src/backend/first-time-setup.service.ts +0 -17
- package/src/backend/floor.service.ts +0 -84
- package/src/backend/index.ts +0 -4
- package/src/backend/print-completions.service.ts +0 -11
- package/src/backend/printer-file.service.ts +0 -91
- package/src/backend/printer-group.service.ts +0 -62
- package/src/backend/printer-job.service.ts +0 -20
- package/src/backend/printer-settings.service.ts +0 -28
- package/src/backend/printers.service.ts +0 -136
- package/src/backend/server-private.service.ts +0 -55
- package/src/backend/server.api.ts +0 -132
- package/src/backend/settings.service.ts +0 -85
- package/src/backend/user.service.ts +0 -51
- package/src/components/AboutHelp/AboutView.vue +0 -164
- package/src/components/CameraGrid/CameraGridView.vue +0 -111
- package/src/components/FirstTimeSetup/FirstTimeSetupView.vue +0 -354
- package/src/components/Generic/Actions/PrinterConnectionAction.vue +0 -56
- package/src/components/Generic/Actions/PrinterCreateAction.vue +0 -22
- package/src/components/Generic/Actions/PrinterDeleteAction.vue +0 -29
- package/src/components/Generic/Actions/PrinterQuickStopAction.vue +0 -35
- package/src/components/Generic/Actions/PrinterSettingsAction.vue +0 -35
- package/src/components/Generic/Actions/PrinterUrlAction.vue +0 -24
- package/src/components/Generic/Actions/RefreshFilesAction.vue +0 -50
- package/src/components/Generic/Actions/SyncPrinterNameAction.vue +0 -36
- package/src/components/Generic/Dialogs/AddOrUpdateCameraStreamDialog.vue +0 -131
- package/src/components/Generic/Dialogs/AddOrUpdateFloorDialog.vue +0 -141
- package/src/components/Generic/Dialogs/AddOrUpdatePrinterDialog.vue +0 -303
- package/src/components/Generic/Dialogs/BaseDialog.vue +0 -81
- package/src/components/Generic/Dialogs/BatchJsonCreateDialog.vue +0 -109
- package/src/components/Generic/Dialogs/BatchReprintDialog.vue +0 -190
- package/src/components/Generic/Dialogs/PrinterChecksPanel.vue +0 -37
- package/src/components/Generic/Dialogs/PrinterControlDialog.vue +0 -202
- package/src/components/Generic/Dialogs/PrinterMaintenanceDialog.vue +0 -130
- package/src/components/Generic/Dialogs/YamlImportExportDialog.vue +0 -186
- package/src/components/Generic/Dialogs/dialog.constants.ts +0 -19
- package/src/components/Generic/FileExplorerSideNav.vue +0 -734
- package/src/components/Generic/Loaders/GridLoader.vue +0 -68
- package/src/components/Generic/NavigationDrawer.vue +0 -69
- package/src/components/Generic/PrintJobsMenu.vue +0 -148
- package/src/components/Generic/Snackbars/AppErrorSnackbar.vue +0 -64
- package/src/components/Generic/Snackbars/AppInfoSnackbar.vue +0 -63
- package/src/components/Generic/Snackbars/AppProgressSnackbar.vue +0 -158
- package/src/components/Generic/Vuetify/TooltipButton.vue +0 -47
- package/src/components/HelpOverlay/HelpOverlay.vue +0 -57
- package/src/components/Login/LoginForm.vue +0 -206
- package/src/components/Login/LoginView.spec.ts +0 -64
- package/src/components/Login/LoginView.vue +0 -65
- package/src/components/Login/Logo.vue +0 -13
- package/src/components/Login/PermissionDenied.vue +0 -109
- package/src/components/Login/RegistrationForm.vue +0 -207
- package/src/components/Login/RegistrationView.vue +0 -17
- package/src/components/Login/__snapshots__/LoginView.spec.ts.snap +0 -1051
- package/src/components/NotFound/NotFoundView.vue +0 -39
- package/src/components/PrintStatistics/PrintStatistics.vue +0 -168
- package/src/components/PrintStatistics/PrintStatisticsView.vue +0 -15
- package/src/components/PrinterGrid/HomeToolbar.vue +0 -90
- package/src/components/PrinterGrid/PrinterGrid.vue +0 -164
- package/src/components/PrinterGrid/PrinterGridTile.vue +0 -438
- package/src/components/PrinterGrid/PrinterGridView.vue +0 -210
- package/src/components/PrinterList/FileControlList.vue +0 -40
- package/src/components/PrinterList/PrinterDetails.vue +0 -91
- package/src/components/PrinterList/PrintersView.vue +0 -492
- package/src/components/Settings/AccountSettings.vue +0 -163
- package/src/components/Settings/DiagnosticsSettings.vue +0 -137
- package/src/components/Settings/EmergencyCommands.vue +0 -265
- package/src/components/Settings/FloorSettings.vue +0 -276
- package/src/components/Settings/GridSettings.vue +0 -127
- package/src/components/Settings/OctoPrintSettings.vue +0 -188
- package/src/components/Settings/ServerProtectionSettings.vue +0 -370
- package/src/components/Settings/SettingsView.vue +0 -73
- package/src/components/Settings/SoftwareUpgradeSettings.vue +0 -297
- package/src/components/Settings/UserManagementSettings.vue +0 -257
- package/src/components/TopBar.vue +0 -147
- package/src/components.d.ts +0 -70
- package/src/directives/file-upload.directive.ts +0 -117
- package/src/directives/printer-drop-position.directive.ts +0 -92
- package/src/env.d.ts +0 -6
- package/src/main.ts +0 -76
- package/src/models/batch/reprint.dto.ts +0 -79
- package/src/models/batch.model.ts +0 -11
- package/src/models/camera-streams/camera-stream.ts +0 -19
- package/src/models/floors/floor.model.ts +0 -30
- package/src/models/octoprint/connection-options.model.ts +0 -8
- package/src/models/plugins/firmware-updates/prusa-firmware-release.model.ts +0 -57
- package/src/models/print-completions/print-completions.model.ts +0 -49
- package/src/models/printers/crud/create-printer.model.ts +0 -26
- package/src/models/printers/file-upload-commands.model.ts +0 -4
- package/src/models/printers/gcode/gcode-analysis.model.ts +0 -30
- package/src/models/printers/printer-current-job.model.ts +0 -90
- package/src/models/printers/printer-file.model.ts +0 -48
- package/src/models/printers/printer.model.ts +0 -18
- package/src/models/server/client-releases.model.ts +0 -27
- package/src/models/server/export-yaml.model.ts +0 -11
- package/src/models/server/features.model.ts +0 -37
- package/src/models/server/github-rate-limit.model.ts +0 -21
- package/src/models/server/version.model.ts +0 -14
- package/src/models/settings/printer-file-clean-settings.model.ts +0 -5
- package/src/models/settings/server-settings.dto.ts +0 -19
- package/src/models/settings/settings.model.ts +0 -57
- package/src/models/socketio-messages/socketio-message.model.ts +0 -53
- package/src/models/uploads/queued-upload.model.ts +0 -12
- package/src/models/user.model.ts +0 -15
- package/src/plugins/README.md +0 -3
- package/src/plugins/index.ts +0 -17
- package/src/plugins/vuetify.ts +0 -53
- package/src/router/index.ts +0 -192
- package/src/router/route-names.ts +0 -14
- package/src/router/utils.ts +0 -23
- package/src/shared/alert.events.ts +0 -14
- package/src/shared/app.constants.ts +0 -23
- package/src/shared/auth.constants.ts +0 -34
- package/src/shared/dialog.composable.ts +0 -41
- package/src/shared/drag.constants.ts +0 -19
- package/src/shared/experimental.constants.ts +0 -1
- package/src/shared/http-client.ts +0 -162
- package/src/shared/noun-adjectives.data.ts +0 -24
- package/src/shared/printer-grid.constants.ts +0 -5
- package/src/shared/printer-state.constants.ts +0 -194
- package/src/shared/snackbar.composable.ts +0 -66
- package/src/shared/socketio.service.ts +0 -104
- package/src/store/auth.store.ts +0 -255
- package/src/store/connection.store.ts +0 -66
- package/src/store/dialog.store.ts +0 -114
- package/src/store/features.store.ts +0 -57
- package/src/store/floor.store.ts +0 -173
- package/src/store/grid.store.ts +0 -10
- package/src/store/index.ts +0 -4
- package/src/store/printer-state.store.ts +0 -246
- package/src/store/printer.store.ts +0 -236
- package/src/store/profile.store.ts +0 -25
- package/src/store/settings.store.ts +0 -64
- package/src/store/test-printer.store.ts +0 -70
- package/src/store/uploads.store.ts +0 -75
- package/src/styles/README.md +0 -3
- package/src/styles/settings.scss +0 -10
- package/src/types/global.d.ts +0 -15
- package/src/utils/array.utils.ts +0 -15
- package/src/utils/date.utils.ts +0 -5
- package/src/utils/download-file.util.ts +0 -25
- package/src/utils/error.utils.ts +0 -3
- package/src/utils/file-size.util.ts +0 -11
- package/src/utils/id.type.ts +0 -1
- package/src/utils/sentry.util.ts +0 -8
- package/src/utils/test.util.ts +0 -30
- package/src/utils/time.utils.ts +0 -2
- package/src/utils/uploads-state.utils.ts +0 -58
- package/src/utils/validation.utils.ts +0 -14
- package/src/vite-env.d.ts +0 -7
- package/test/setup-axios-mock.ts +0 -15
- /package/{src/assets/logo.png → dist/assets/logo-CJVdjy51.png} +0 -0
- /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
|
-
}
|
package/src/store/auth.store.ts
DELETED
|
@@ -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
|
-
}
|