libshv-js 3.16.1 → 3.20.0

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.
@@ -1,36 +1,48 @@
1
- import {computed, ComputedRef, Ref, ref, watchEffect} from 'vue';
2
- import {WsClient, WsClientOptionsLogin} from './ws-client';
3
- import {useLocalStorage, useSessionStorage} from '@vueuse/core';
4
- import PKCE from 'js-pkce';
5
- import * as z from './zod';
6
- import {RpcValue} from './rpcvalue';
7
-
8
- type GlobalResourceOptions<ResourceType> = {
9
- shvPath: string;
10
- method: string;
11
- validator: z.ZodType<ResourceType>;
12
- signalName: string;
13
- signalHandler: (param: RpcValue, resource: Ref<ResourceType | undefined>, reinit: () => void) => void;
14
- };
15
-
16
- type VueShvOptions = {
17
- wsUri: string;
18
- onRequest: WsClientOptionsLogin['onRequest'];
19
- azureCodeRedirect?: string;
20
- };
21
-
22
- type ShvLocalStorage = {
23
- azureAccessToken?: string;
24
- azureRedirectTo?: string;
25
- };
26
-
27
- type ShvSessionStorage = {
28
- shvLoginUser?: string;
29
- shvLoginPassword?: string;
30
-
31
- azureWorkflow?: z.infer<typeof OAuth2AzureWorkflowZod>;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
37
  };
33
-
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.fullReloadHandler = exports.azure = exports.LoginFailureReason = void 0;
40
+ exports.useShv = useShv;
41
+ const vue_1 = require("vue");
42
+ const ws_client_1 = require("./ws-client");
43
+ const core_1 = require("@vueuse/core");
44
+ const js_pkce_1 = __importDefault(require("js-pkce"));
45
+ const z = __importStar(require("./zod"));
34
46
  const OAuth2AzureWorkflowZod = z.map({
35
47
  type: z.literal('oauth2-azure'),
36
48
  authorizeUrl: z.string(),
@@ -38,22 +50,16 @@ const OAuth2AzureWorkflowZod = z.map({
38
50
  clientId: z.string(),
39
51
  scopes: z.string().or(z.array(z.string())),
40
52
  });
41
-
42
- export enum LoginFailureReason {
43
- NoCredentials,
44
- AzureTimedOut,
45
- AzureUnsupported,
46
- CouldntLogin,
47
- LoggedOut,
48
- }
49
-
50
- type LoginFailure = {
51
- reason: LoginFailureReason;
52
- message?: string;
53
- };
54
-
55
- const makePkce = (oauthOptions: {azureCodeRedirect: string, clientId: string; authorizeUrl: string; tokenUrl: string; scopes: string | string[]}) => {
56
- const pkce = new PKCE({
53
+ var LoginFailureReason;
54
+ (function (LoginFailureReason) {
55
+ LoginFailureReason[LoginFailureReason["NoCredentials"] = 0] = "NoCredentials";
56
+ LoginFailureReason[LoginFailureReason["AzureTimedOut"] = 1] = "AzureTimedOut";
57
+ LoginFailureReason[LoginFailureReason["AzureUnsupported"] = 2] = "AzureUnsupported";
58
+ LoginFailureReason[LoginFailureReason["CouldntLogin"] = 3] = "CouldntLogin";
59
+ LoginFailureReason[LoginFailureReason["LoggedOut"] = 4] = "LoggedOut";
60
+ })(LoginFailureReason || (exports.LoginFailureReason = LoginFailureReason = {}));
61
+ const makePkce = (oauthOptions) => {
62
+ const pkce = new js_pkce_1.default({
57
63
  client_id: oauthOptions.clientId,
58
64
  redirect_uri: (() => {
59
65
  const url = new URL(globalThis.location.href);
@@ -67,65 +73,49 @@ const makePkce = (oauthOptions: {azureCodeRedirect: string, clientId: string; au
67
73
  });
68
74
  return pkce;
69
75
  };
70
-
71
- export {makePkce as azure};
72
-
73
- export function useShv(options: VueShvOptions) {
74
- const shvLocalStorage = useLocalStorage<ShvLocalStorage>('vue-shv', {});
75
- const shvSessionStorage = useSessionStorage<ShvSessionStorage>('vue-shv', {});
76
-
77
- const displayName = ref('Loading...');
78
- const displayShortName = ref('');
79
- const displayFullName = ref('');
80
- const displayEmail = ref('');
81
- const displayPhoto = ref<string>();
82
-
76
+ exports.azure = makePkce;
77
+ function useShv(options) {
78
+ const shvLocalStorage = (0, core_1.useLocalStorage)('vue-shv', {});
79
+ const shvSessionStorage = (0, core_1.useSessionStorage)('vue-shv', {});
80
+ const displayName = (0, vue_1.ref)('Loading...');
81
+ const displayShortName = (0, vue_1.ref)('');
82
+ const displayFullName = (0, vue_1.ref)('');
83
+ const displayEmail = (0, vue_1.ref)('');
84
+ const displayPhoto = (0, vue_1.ref)();
83
85
  const state = {
84
- ws: undefined as WsClient | undefined,
85
- reconnectService: undefined as ReturnType<typeof globalThis.setTimeout> | undefined,
86
+ ws: undefined,
87
+ reconnectService: undefined,
86
88
  };
87
-
88
- const waitingForSocket: Array<{
89
- resolve: (value: WsClient) => void;
90
- reject: () => void;
91
- }> = [];
92
-
89
+ const waitingForSocket = [];
93
90
  const resetAzureToken = () => {
94
91
  shvLocalStorage.value.azureAccessToken = undefined;
95
92
  };
96
-
97
93
  const azureAvailable = async () => {
98
94
  const accessToken = shvLocalStorage.value.azureAccessToken;
99
95
  if (accessToken === undefined) {
100
96
  return LoginFailureReason.NoCredentials;
101
97
  }
102
-
103
98
  const resp = await fetch('https://graph.microsoft.com/v1.0/me', {
104
99
  headers: {
105
100
  Authorization: `Bearer ${accessToken}`,
106
101
  },
107
102
  });
108
-
109
- const json = await resp.json() as unknown;
110
-
103
+ const json = await resp.json();
111
104
  if (typeof json === 'object' && json !== null) {
112
105
  if ('displayName' in json && typeof json.displayName === 'string') {
113
106
  displayName.value = json.displayName;
114
107
  }
115
-
116
108
  if ('givenName' in json && typeof json.givenName === 'string'
117
109
  && 'surname' in json && typeof json.surname === 'string') {
118
- const firstName: string = json.givenName;
119
- const lastname: string = json.surname;
110
+ const firstName = json.givenName;
111
+ const lastname = json.surname;
120
112
  displayShortName.value = firstName.charAt(0) + lastname.charAt(0);
121
113
  displayFullName.value = firstName + ' ' + lastname;
122
114
  }
123
-
124
115
  if ('mail' in json && typeof json.mail === 'string') {
125
116
  displayEmail.value = json.mail;
126
117
  }
127
118
  }
128
-
129
119
  const photo = await fetch('https://graph.microsoft.com/v1.0/me/photos/48x48/$value', {
130
120
  headers: {
131
121
  Authorization: `Bearer ${accessToken}`,
@@ -134,26 +124,20 @@ export function useShv(options: VueShvOptions) {
134
124
  if (photo.ok) {
135
125
  displayPhoto.value = URL.createObjectURL(await photo.blob());
136
126
  }
137
-
138
127
  if (!resp.ok) {
139
128
  resetAzureToken();
140
129
  }
141
-
142
130
  return resp.ok ? 'azureAvailable' : LoginFailureReason.AzureTimedOut;
143
131
  };
144
-
145
- const debug = (...args: string[]) => {
132
+ const debug = (...args) => {
146
133
  logContents.value = logContents.value + args.join(' ') + '\n';
147
134
  console.debug(...args);
148
135
  };
149
-
150
- const azureAuth = (redirectTo?: string) => {
136
+ const azureAuth = (redirectTo) => {
151
137
  if (options.azureCodeRedirect === undefined) {
152
138
  throw new Error('Azure redirect URL not set');
153
139
  }
154
-
155
- const {azureCodeRedirect} = options;
156
-
140
+ const { azureCodeRedirect } = options;
157
141
  shvLocalStorage.value.azureRedirectTo = redirectTo ?? globalThis.location.pathname;
158
142
  const noBrokerSupport = () => {
159
143
  loginFailure.value = {
@@ -161,8 +145,7 @@ export function useShv(options: VueShvOptions) {
161
145
  message: 'Broker does not support Azure',
162
146
  };
163
147
  };
164
-
165
- state.ws = new WsClient({
148
+ state.ws = new ws_client_1.WsClient({
166
149
  logDebug: debug,
167
150
  wsUri: options.wsUri,
168
151
  onWorkflows(workflows) {
@@ -170,16 +153,13 @@ export function useShv(options: VueShvOptions) {
170
153
  noBrokerSupport();
171
154
  return;
172
155
  }
173
-
174
156
  for (const workflow of workflows) {
175
157
  const parsedWorkflow = OAuth2AzureWorkflowZod.safeParse(workflow);
176
158
  if (!parsedWorkflow.success) {
177
159
  continue;
178
160
  }
179
-
180
161
  shvSessionStorage.value.azureWorkflow = parsedWorkflow.data;
181
-
182
- globalThis.location.replace(makePkce({...parsedWorkflow.data, azureCodeRedirect}).authorizeUrl());
162
+ globalThis.location.replace(makePkce({ ...parsedWorkflow.data, azureCodeRedirect }).authorizeUrl());
183
163
  }
184
164
  },
185
165
  onWorkflowsFailed() {
@@ -187,57 +167,46 @@ export function useShv(options: VueShvOptions) {
187
167
  },
188
168
  });
189
169
  };
190
-
191
- const setShvCredentials = (userName: string, password: string) => {
170
+ const setShvCredentials = (userName, password) => {
192
171
  shvLogout();
193
172
  shvSessionStorage.value.shvLoginUser = userName;
194
173
  shvSessionStorage.value.shvLoginPassword = password;
195
174
  };
196
-
197
- const rpcCall = async (shvPath: string, method: string, params?: RpcValue) => {
175
+ const rpcCall = async (shvPath, method, params) => {
198
176
  const shv = await getConnection();
199
177
  return shv.callRpcMethod(shvPath, method, params);
200
178
  };
201
-
202
- const makeRpcCall = <ResultType>(shvPath: string, method: string, validator: z.ZodType<ResultType>) => async () => {
179
+ const makeRpcCall = (shvPath, method, validator) => async () => {
203
180
  const resultOrError = await rpcCall(shvPath, method);
204
181
  if (resultOrError instanceof Error) {
205
182
  return resultOrError;
206
183
  }
207
-
208
184
  const parsed = validator.safeParse(resultOrError);
209
185
  if (!parsed.success) {
210
186
  return new Error(parsed.error.message);
211
187
  }
212
-
213
188
  return parsed.data;
214
189
  };
215
-
216
- const makeRpcCallParam = <ResultType, ParamType extends RpcValue>(shvPath: string, method: string, _paramType: z.ZodType<ParamType>, validator: z.ZodType<ResultType>) => async (param: ParamType) => {
190
+ const makeRpcCallParam = (shvPath, method, _paramType, validator) => async (param) => {
217
191
  const resultOrError = await rpcCall(shvPath, method, param);
218
192
  if (resultOrError instanceof Error) {
219
193
  return resultOrError;
220
194
  }
221
-
222
195
  const parsed = validator.safeParse(resultOrError);
223
196
  if (!parsed.success) {
224
197
  return new Error(parsed.error.message);
225
198
  }
226
-
227
199
  return parsed.data;
228
200
  };
229
-
230
- const connected = ref<'connected' | 'connecting' | 'disconnected'>('disconnected');
231
- const logContents = ref('');
201
+ const connected = (0, vue_1.ref)('disconnected');
202
+ const logContents = (0, vue_1.ref)('');
232
203
  const shvLogout = () => {
233
204
  resetAzureToken();
234
205
  shvSessionStorage.value.shvLoginUser = undefined;
235
206
  shvSessionStorage.value.shvLoginPassword = undefined;
236
-
237
207
  for (const waiter of waitingForSocket) {
238
208
  waiter.reject();
239
209
  }
240
-
241
210
  connected.value = 'disconnected';
242
211
  waitingForSocket.length = 0;
243
212
  state.ws?.close();
@@ -245,23 +214,19 @@ export function useShv(options: VueShvOptions) {
245
214
  displayPhoto.value = undefined;
246
215
  state.ws = undefined;
247
216
  };
248
-
249
- const loginFailure = ref<LoginFailure>();
250
-
217
+ const loginFailure = (0, vue_1.ref)();
251
218
  const getConnection = async () => {
252
219
  if (connected.value === 'connected') {
253
- return state.ws!;
220
+ return state.ws;
254
221
  }
255
-
256
- return new Promise<WsClient>((resolve, reject) => {
257
- waitingForSocket.push({resolve, reject});
222
+ return new Promise((resolve, reject) => {
223
+ waitingForSocket.push({ resolve, reject });
258
224
  if (connected.value === 'connecting') {
259
225
  // We should try to connect only once at the same time.
260
226
  return;
261
227
  }
262
-
263
228
  connected.value = 'connecting';
264
- const doConnect = (user: string, password: string, loginType: 'PLAIN' | 'TOKEN') => {
229
+ const doConnect = (user, password, loginType) => {
265
230
  console.log('Connecting to', options.wsUri);
266
231
  const makeLoginOptions = () => {
267
232
  switch (loginType) {
@@ -278,17 +243,15 @@ export function useShv(options: VueShvOptions) {
278
243
  };
279
244
  }
280
245
  };
281
-
282
- state.ws = new WsClient({
246
+ state.ws = new ws_client_1.WsClient({
283
247
  login: makeLoginOptions(),
284
248
  wsUri: options.wsUri,
285
249
  timeout: 120_000,
286
250
  logDebug: debug,
287
251
  onConnected() {
288
252
  for (const waiter of waitingForSocket) {
289
- waiter.resolve(state.ws!);
253
+ waiter.resolve(state.ws);
290
254
  }
291
-
292
255
  waitingForSocket.length = 0;
293
256
  console.log('Connected to', options.wsUri);
294
257
  connected.value = 'connected';
@@ -314,7 +277,6 @@ export function useShv(options: VueShvOptions) {
314
277
  onRequest: options.onRequest,
315
278
  });
316
279
  };
317
-
318
280
  const shvUser = shvSessionStorage.value.shvLoginUser;
319
281
  const shvPassword = shvSessionStorage.value.shvLoginPassword;
320
282
  if (shvUser !== undefined && shvPassword !== undefined) {
@@ -324,7 +286,6 @@ export function useShv(options: VueShvOptions) {
324
286
  doConnect(shvUser, shvPassword, 'PLAIN');
325
287
  return;
326
288
  }
327
-
328
289
  azureAvailable().then(isAzureAvailable => {
329
290
  switch (isAzureAvailable) {
330
291
  case LoginFailureReason.NoCredentials:
@@ -337,13 +298,11 @@ export function useShv(options: VueShvOptions) {
337
298
  case 'azureAvailable':
338
299
  break;
339
300
  }
340
-
341
301
  const accessToken = shvLocalStorage.value.azureAccessToken;
342
-
343
302
  if (accessToken !== undefined) {
344
303
  doConnect('', accessToken, 'TOKEN');
345
304
  }
346
- }).catch((error: unknown) => {
305
+ }).catch((error) => {
347
306
  console.error('Failed to fetch verify azure info, redirecting to the login page in 3 seconds', error);
348
307
  setTimeout(() => {
349
308
  loginFailure.value = {
@@ -354,91 +313,74 @@ export function useShv(options: VueShvOptions) {
354
313
  });
355
314
  });
356
315
  };
357
-
358
- function makeGlobalResource<ResourceType>(options: GlobalResourceOptions<ResourceType>): () => Ref<ResourceType | undefined>;
359
- function makeGlobalResource<ResourceType>(options: GlobalResourceOptions<ResourceType> & {default: ResourceType}): () => ComputedRef<ResourceType>;
360
- function makeGlobalResource<ResourceType>(options: GlobalResourceOptions<ResourceType> & {default?: ResourceType}): () => ComputedRef<ResourceType> | Ref<ResourceType | undefined> {
361
- const resource = ref<ResourceType>();
316
+ function makeGlobalResource(options) {
317
+ const resource = (0, vue_1.ref)();
362
318
  const resIdentifier = `${options.shvPath}:${options.method}`;
363
-
364
- const resourceCall = makeRpcCall<ResourceType>(options.shvPath, options.method, options.validator);
319
+ const resourceCall = makeRpcCall(options.shvPath, options.method, options.validator);
365
320
  const refreshValue = async () => {
366
321
  const newResource = await resourceCall();
367
322
  if (newResource instanceof Error) {
368
323
  return;
369
324
  }
370
-
371
325
  resource.value = newResource;
372
326
  };
373
-
374
327
  const initialize = async () => {
375
328
  try {
376
329
  await refreshValue();
377
330
  const connection = await getConnection();
378
- connection.subscribe(`Global-${resIdentifier}:`, options.shvPath, options.signalName, (_path: string, _method: string, param: RpcValue) => {
379
- options.signalHandler(param, resource, async () => refreshValue().catch((error: unknown) => {
331
+ connection.subscribe(`Global-${resIdentifier}:`, options.shvPath, options.signalName, (_path, _method, param) => {
332
+ options.signalHandler(param, resource, async () => refreshValue().catch((error) => {
380
333
  console.error(`Failed to initialize ${resIdentifier}`, error);
381
334
  }));
382
335
  });
383
- } catch (error) {
336
+ }
337
+ catch (error) {
384
338
  console.error(`Failed to initialize ${resIdentifier}`, error);
385
339
  }
386
340
  };
387
-
388
341
  let initialized = false;
389
-
390
342
  return () => {
391
343
  if (!initialized) {
392
344
  initialized = true;
393
- watchEffect(() => {
345
+ (0, vue_1.watchEffect)(() => {
394
346
  if (connected.value !== 'connected') {
395
347
  return;
396
348
  }
397
-
398
- initialize().catch((error: unknown) => {
349
+ initialize().catch((error) => {
399
350
  console.error(`Failed to initialize ${resIdentifier}`, error);
400
351
  });
401
352
  });
402
353
  }
403
-
404
354
  if ('default' in options) {
405
355
  const defaultValue = options.default;
406
- const withDefault = computed(() => {
356
+ const withDefault = (0, vue_1.computed)(() => {
407
357
  if (resource.value === undefined) {
408
358
  return defaultValue;
409
359
  }
410
-
411
360
  return resource.value;
412
361
  });
413
362
  return withDefault;
414
363
  }
415
-
416
364
  return resource;
417
365
  };
418
366
  }
419
-
420
- const azureHandlerError = ref('');
421
-
367
+ const azureHandlerError = (0, vue_1.ref)('');
422
368
  const handleAzureCode = async () => {
423
369
  if (shvSessionStorage.value.azureWorkflow === undefined) {
424
370
  azureHandlerError.value = 'Azure error: no active login procedure';
425
371
  return;
426
372
  }
427
-
428
373
  if (options.azureCodeRedirect === undefined) {
429
374
  throw new Error('Azure redirect URL not set');
430
375
  }
431
-
432
- const {azureCodeRedirect} = options;
433
-
434
- return makePkce({...shvSessionStorage.value.azureWorkflow, azureCodeRedirect}).exchangeForAccessToken(globalThis.location.href).then(resp => {
376
+ const { azureCodeRedirect } = options;
377
+ return makePkce({ ...shvSessionStorage.value.azureWorkflow, azureCodeRedirect }).exchangeForAccessToken(globalThis.location.href).then(resp => {
435
378
  shvSessionStorage.value.azureWorkflow = undefined;
436
379
  const token = resp.access_token;
437
380
  if (token === undefined) {
438
381
  azureHandlerError.value = 'Couldn\'t authenticate to Azure: unable to exchange access token';
439
382
  return;
440
383
  }
441
-
442
384
  // Store the token and remove the code from the query params.
443
385
  shvLogout();
444
386
  shvLocalStorage.value.azureAccessToken = token;
@@ -447,14 +389,12 @@ export function useShv(options: VueShvOptions) {
447
389
  azureHandlerError.value = 'Couldn\'t authenticate to Azure: no redirect URL';
448
390
  return;
449
391
  }
450
-
451
392
  shvLocalStorage.value.azureRedirectTo = undefined;
452
393
  return redirectTo;
453
- }).catch((error: unknown) => {
394
+ }).catch((error) => {
454
395
  azureHandlerError.value = `Couldn't authenticate to Azure: ${JSON.stringify(error)}`;
455
396
  });
456
397
  };
457
-
458
398
  return {
459
399
  azureAuth,
460
400
  azureHandlerError,
@@ -478,7 +418,7 @@ export function useShv(options: VueShvOptions) {
478
418
  shvSessionStorage,
479
419
  };
480
420
  }
481
-
482
- export const fullReloadHandler = (_param: RpcValue, _resource: unknown, reinit: () => void) => {
421
+ const fullReloadHandler = (_param, _resource, reinit) => {
483
422
  reinit();
484
423
  };
424
+ exports.fullReloadHandler = fullReloadHandler;