@umbraco-cms/backoffice 14.0.0--preview005-2dd3b083 → 14.0.0--preview005-7ef2bd26

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 (56) hide show
  1. package/dist-cms/apps/app/app.element.js +19 -15
  2. package/dist-cms/custom-elements.json +40 -6
  3. package/dist-cms/libs/element-api/element.mixin.d.ts +3 -3
  4. package/dist-cms/libs/element-api/element.mixin.js +2 -2
  5. package/dist-cms/libs/extension-api/registry/extension.registry.d.ts +19 -0
  6. package/dist-cms/libs/extension-api/registry/extension.registry.js +42 -1
  7. package/dist-cms/libs/localization-api/index.d.ts +2 -2
  8. package/dist-cms/libs/localization-api/index.js +2 -2
  9. package/dist-cms/libs/localization-api/{localize.controller.d.ts → localization.controller.d.ts} +6 -4
  10. package/dist-cms/libs/localization-api/{localize.controller.js → localization.controller.js} +34 -24
  11. package/dist-cms/libs/localization-api/localization.manager.d.ts +29 -0
  12. package/dist-cms/libs/localization-api/localization.manager.js +94 -0
  13. package/dist-cms/mocks/data/data-type/data-type.data.js +7 -0
  14. package/dist-cms/mocks/data/document-type/document-type.data.js +26 -0
  15. package/dist-cms/packages/block/block/workspace/block-workspace.context.js +0 -1
  16. package/dist-cms/packages/block/block-grid/property-editors/block-grid-group-configuration/manifests.d.ts +2 -0
  17. package/dist-cms/packages/block/block-grid/property-editors/block-grid-group-configuration/manifests.js +11 -0
  18. package/dist-cms/packages/block/block-grid/property-editors/block-grid-group-configuration/property-editor-ui-block-grid-group-configuration.element.d.ts +19 -0
  19. package/dist-cms/packages/block/block-grid/property-editors/block-grid-group-configuration/property-editor-ui-block-grid-group-configuration.element.js +61 -0
  20. package/dist-cms/packages/block/block-grid/property-editors/block-grid-type-configuration/property-editor-ui-block-grid-type-configuration.element.d.ts +10 -3
  21. package/dist-cms/packages/block/block-grid/property-editors/block-grid-type-configuration/property-editor-ui-block-grid-type-configuration.element.js +130 -11
  22. package/dist-cms/packages/block/block-grid/property-editors/manifests.js +8 -1
  23. package/dist-cms/packages/block/block-grid/types.d.ts +9 -2
  24. package/dist-cms/packages/block/block-grid/types.js +1 -1
  25. package/dist-cms/packages/block/block-list/property-editors/block-list-type-configuration/property-editor-ui-block-list-type-configuration.element.d.ts +3 -0
  26. package/dist-cms/packages/block/block-list/property-editors/block-list-type-configuration/property-editor-ui-block-list-type-configuration.element.js +41 -3
  27. package/dist-cms/packages/block/block-list/types.d.ts +1 -0
  28. package/dist-cms/packages/block/block-list/types.js +1 -1
  29. package/dist-cms/packages/block/block-type/components/index.d.ts +1 -1
  30. package/dist-cms/packages/block/block-type/components/index.js +1 -1
  31. package/dist-cms/packages/block/block-type/components/input-block-type/input-block-type.element.d.ts +1 -3
  32. package/dist-cms/packages/block/block-type/components/input-block-type/input-block-type.element.js +42 -46
  33. package/dist-cms/packages/block/block-type/workspace/block-type-workspace.context.d.ts +4 -4
  34. package/dist-cms/packages/block/block-type/workspace/block-type-workspace.context.js +3 -1
  35. package/dist-cms/packages/block/block-type/workspace/block-type-workspace.element.js +4 -2
  36. package/dist-cms/packages/core/localization/registry/localization.registry.d.ts +3 -3
  37. package/dist-cms/packages/core/localization/registry/localization.registry.js +59 -60
  38. package/dist-cms/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.js +1 -1
  39. package/dist-cms/packages/documents/document-types/workspace/views/design/document-type-workspace-view-edit.element.js +1 -1
  40. package/dist-cms/packages/media/media-types/workspace/views/design/media-type-workspace-view-edit.element.js +1 -1
  41. package/dist-cms/packages/user/current-user/current-user.context.js +2 -7
  42. package/dist-cms/shared/auth/auth-flow.d.ts +0 -2
  43. package/dist-cms/shared/auth/auth-flow.js +28 -9
  44. package/dist-cms/shared/auth/auth.context.d.ts +14 -5
  45. package/dist-cms/shared/auth/auth.context.js +15 -3
  46. package/dist-cms/shared/auth/auth.context.token.d.ts +4 -2
  47. package/dist-cms/shared/auth/auth.context.token.js +2 -0
  48. package/dist-cms/shared/auth/index.d.ts +0 -1
  49. package/dist-cms/shared/auth/index.js +0 -1
  50. package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
  51. package/dist-cms/vscode-html-custom-data.json +23 -5
  52. package/package.json +1 -1
  53. package/dist-cms/libs/localization-api/manager.d.ts +0 -18
  54. package/dist-cms/libs/localization-api/manager.js +0 -40
  55. package/dist-cms/shared/auth/auth.context.interface.d.ts +0 -39
  56. package/dist-cms/shared/auth/auth.context.interface.js +0 -1
@@ -1,11 +1,11 @@
1
- import type { UmbBlockTypeBaseModel } from '../types.js';
1
+ import type { UmbBlockTypeWithGroupKey } from '../types.js';
2
2
  import type { UmbPropertyDatasetContext } from '../../../core/property/index.js';
3
3
  import type { UmbInvariantableWorkspaceContextInterface, UmbWorkspaceContextInterface } from '../../../core/workspace/index.js';
4
4
  import { UmbEditableWorkspaceContextBase } from '../../../core/workspace/index.js';
5
5
  import type { UmbControllerHost, UmbControllerHostElement } from '../../../../libs/controller-api/index.js';
6
6
  import { UmbContextToken } from '../../../../libs/context-api/index.js';
7
7
  import type { ManifestWorkspace, PropertyEditorConfigProperty } from '../../../core/extension-registry/index.js';
8
- export declare class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeBaseModel = UmbBlockTypeBaseModel> extends UmbEditableWorkspaceContextBase<BlockTypeData> implements UmbInvariantableWorkspaceContextInterface {
8
+ export declare class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeWithGroupKey = UmbBlockTypeWithGroupKey> extends UmbEditableWorkspaceContextBase<BlockTypeData> implements UmbInvariantableWorkspaceContextInterface {
9
9
  #private;
10
10
  readonly IS_BLOCK_TYPE_WORKSPACE_CONTEXT = true;
11
11
  readonly data: import("rxjs").Observable<BlockTypeData | undefined>;
@@ -17,7 +17,7 @@ export declare class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlock
17
17
  });
18
18
  createPropertyDatasetContext(host: UmbControllerHost): UmbPropertyDatasetContext;
19
19
  load(unique: string): Promise<void>;
20
- create(contentElementTypeId: string): Promise<{
20
+ create(contentElementTypeId: string, groupKey?: string | null): Promise<{
21
21
  data: BlockTypeData;
22
22
  }>;
23
23
  getData(): BlockTypeData | undefined;
@@ -32,4 +32,4 @@ export declare class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlock
32
32
  destroy(): void;
33
33
  }
34
34
  export default UmbBlockTypeWorkspaceContext;
35
- export declare const UMB_BLOCK_TYPE_WORKSPACE_CONTEXT: UmbContextToken<UmbWorkspaceContextInterface, UmbBlockTypeWorkspaceContext<UmbBlockTypeBaseModel>>;
35
+ export declare const UMB_BLOCK_TYPE_WORKSPACE_CONTEXT: UmbContextToken<UmbWorkspaceContextInterface, UmbBlockTypeWorkspaceContext<UmbBlockTypeWithGroupKey>>;
@@ -48,9 +48,11 @@ export class UmbBlockTypeWorkspaceContext extends UmbEditableWorkspaceContextBas
48
48
  });
49
49
  });
50
50
  }
51
- async create(contentElementTypeId) {
51
+ async create(contentElementTypeId, groupKey) {
52
+ //Only set groupKey property if it exists
52
53
  const data = {
53
54
  contentElementTypeKey: contentElementTypeId,
55
+ ...(groupKey && { groupKey: groupKey }),
54
56
  };
55
57
  this.setIsNew(true);
56
58
  __classPrivateFieldGet(this, _UmbBlockTypeWorkspaceContext_data, "f").setValue(data);
@@ -57,11 +57,13 @@ _UmbBlockTypeWorkspaceElement_gotWorkspaceContext = function _UmbBlockTypeWorksp
57
57
  __classPrivateFieldSet(this, _UmbBlockTypeWorkspaceElement_workspaceContext, context, "f");
58
58
  this._routes = [
59
59
  {
60
- path: 'create/:elementTypeKey',
60
+ // Would it make more sense to have groupKey before elementTypeKey?
61
+ path: 'create/:elementTypeKey/:groupKey',
61
62
  component: __classPrivateFieldGet(this, _UmbBlockTypeWorkspaceElement_editorElement, "f"),
62
63
  setup: async (_component, info) => {
63
64
  const elementTypeKey = info.match.params.elementTypeKey;
64
- __classPrivateFieldGet(this, _UmbBlockTypeWorkspaceElement_workspaceContext, "f").create(elementTypeKey);
65
+ const groupKey = info.match.params.groupKey === 'null' ? null : info.match.params.groupKey;
66
+ __classPrivateFieldGet(this, _UmbBlockTypeWorkspaceElement_workspaceContext, "f").create(elementTypeKey, groupKey);
65
67
  new UmbWorkspaceIsNewRedirectController(this, __classPrivateFieldGet(this, _UmbBlockTypeWorkspaceElement_workspaceContext, "f"), this.shadowRoot.querySelector('umb-router-slot'));
66
68
  },
67
69
  },
@@ -1,12 +1,12 @@
1
- import type { LocalizationSet } from '../../../../libs/localization-api/index.js';
1
+ import type { UmbLocalizationSetBase } from '../../../../libs/localization-api/index.js';
2
2
  import type { UmbBackofficeExtensionRegistry } from '../../extension-registry/index.js';
3
3
  export declare class UmbLocalizationRegistry {
4
4
  #private;
5
+ readonly currentLanguage: import("rxjs/internal/Observable").Observable<string>;
5
6
  /**
6
7
  * Get the current registered translations.
7
8
  */
8
- get localizations(): Map<string, LocalizationSet>;
9
- get isDefaultLoaded(): import("rxjs/internal/Observable").Observable<boolean>;
9
+ get localizations(): Map<string, UmbLocalizationSetBase>;
10
10
  constructor(extensionRegistry: UmbBackofficeExtensionRegistry);
11
11
  /**
12
12
  * Load a language from the extension registry.
@@ -3,72 +3,75 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
3
3
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
- var _UmbLocalizationRegistry_instances, _UmbLocalizationRegistry_currentLanguage, _UmbLocalizationRegistry_isDefaultLoaded, _UmbLocalizationRegistry_addOrUpdateDictionary;
7
- import { registerLocalization, localizations, } from '../../../../libs/localization-api/index.js';
8
- import { hasDefaultExport, loadManifestPlainJs } from '../../../../libs/extension-api/index.js';
6
+ var _UmbLocalizationRegistry_currentLanguage, _UmbLocalizationRegistry_loadedExtAliases, _UmbLocalizationRegistry_loadExtension;
7
+ import { umbLocalizationManager } from '../../../../libs/localization-api/index.js';
9
8
  import { umbExtensionsRegistry } from '../../extension-registry/index.js';
10
- import { BehaviorSubject, Subject, combineLatest, map, distinctUntilChanged, filter, startWith, } from '../../../../external/rxjs/index.js';
9
+ import { UmbStringState } from '../../../../libs/observable-api/index.js';
10
+ import { combineLatest } from '../../../../external/rxjs/index.js';
11
+ import { hasDefaultExport, loadManifestPlainJs } from '../../../../libs/extension-api/index.js';
12
+ function addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary) {
13
+ for (const [key, value] of Object.entries(dictionary)) {
14
+ innerDictionary[`${dictionaryName}_${key}`] = value;
15
+ }
16
+ }
11
17
  export class UmbLocalizationRegistry {
12
18
  /**
13
19
  * Get the current registered translations.
14
20
  */
15
21
  get localizations() {
16
- return localizations;
17
- }
18
- get isDefaultLoaded() {
19
- return __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").asObservable();
22
+ return umbLocalizationManager.localizations;
20
23
  }
21
24
  constructor(extensionRegistry) {
22
- _UmbLocalizationRegistry_instances.add(this);
23
- _UmbLocalizationRegistry_currentLanguage.set(this, new Subject());
24
- _UmbLocalizationRegistry_isDefaultLoaded.set(this, new BehaviorSubject(false));
25
- const currentLanguage$ = __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").pipe(startWith(document.documentElement.lang || 'en-us'), map((x) => x.toLowerCase()), distinctUntilChanged());
26
- const currentExtensions$ = extensionRegistry.extensionsOfType('localization').pipe(filter((x) => x.length > 0), distinctUntilChanged((prev, curr) => prev.length === curr.length && prev.every((x) => curr.includes(x))));
27
- combineLatest([currentLanguage$, currentExtensions$]).subscribe(async ([userCulture, extensions]) => {
28
- const locale = new Intl.Locale(userCulture);
29
- const translations = await Promise.all(extensions
30
- .filter((x) => x.meta.culture.toLowerCase() === locale.baseName.toLowerCase() ||
31
- x.meta.culture.toLowerCase() === locale.language.toLowerCase())
32
- .map(async (extension) => {
33
- const innerDictionary = {};
34
- // If extension contains a dictionary, add it to the inner dictionary.
35
- if (extension.meta.localizations) {
36
- for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) {
37
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_instances, "m", _UmbLocalizationRegistry_addOrUpdateDictionary).call(this, innerDictionary, dictionaryName, dictionary);
38
- }
25
+ _UmbLocalizationRegistry_currentLanguage.set(this, new UmbStringState(document.documentElement.lang ?? 'en-us'));
26
+ this.currentLanguage = __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").asObservable();
27
+ _UmbLocalizationRegistry_loadedExtAliases.set(this, []);
28
+ _UmbLocalizationRegistry_loadExtension.set(this, async (extension) => {
29
+ __classPrivateFieldGet(this, _UmbLocalizationRegistry_loadedExtAliases, "f").push(extension.alias);
30
+ const innerDictionary = {};
31
+ // If extension contains a dictionary, add it to the inner dictionary.
32
+ if (extension.meta.localizations) {
33
+ for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) {
34
+ addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary);
39
35
  }
40
- // If extension contains a js file, load it and add the default dictionary to the inner dictionary.
41
- if (extension.js) {
42
- const loadedExtension = await loadManifestPlainJs(extension.js);
43
- if (loadedExtension && hasDefaultExport(loadedExtension)) {
44
- for (const [dictionaryName, dictionary] of Object.entries(loadedExtension.default)) {
45
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_instances, "m", _UmbLocalizationRegistry_addOrUpdateDictionary).call(this, innerDictionary, dictionaryName, dictionary);
46
- }
36
+ }
37
+ // If extension contains a js file, load it and add the default dictionary to the inner dictionary.
38
+ if (extension.js) {
39
+ const loadedExtension = await loadManifestPlainJs(extension.js);
40
+ if (loadedExtension && hasDefaultExport(loadedExtension)) {
41
+ for (const [dictionaryName, dictionary] of Object.entries(loadedExtension.default)) {
42
+ addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary);
47
43
  }
48
44
  }
49
- // Notify subscribers that the inner dictionary has changed.
50
- return {
51
- $code: extension.meta.culture.toLowerCase(),
52
- $dir: extension.meta.direction ?? 'ltr',
53
- ...innerDictionary,
54
- };
55
- }));
56
- if (translations.length) {
57
- registerLocalization(...translations);
58
- // Set the document language
59
- const newLang = locale.baseName.toLowerCase();
60
- if (document.documentElement.lang.toLowerCase() !== newLang) {
61
- document.documentElement.lang = newLang;
62
- }
63
- // Set the document direction to the direction of the primary language
64
- const newDir = translations[0].$dir ?? 'ltr';
65
- if (document.documentElement.dir !== newDir) {
66
- document.documentElement.dir = newDir;
67
- }
68
45
  }
69
- if (!__classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").value) {
70
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").next(true);
71
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").complete();
46
+ // Notify subscribers that the inner dictionary has changed.
47
+ return {
48
+ $code: extension.meta.culture.toLowerCase(),
49
+ $dir: extension.meta.direction ?? 'ltr',
50
+ ...innerDictionary,
51
+ };
52
+ });
53
+ combineLatest([this.currentLanguage, extensionRegistry.extensionsOfType('localization')]).subscribe(async ([currentLanguage, extensions]) => {
54
+ const locale = new Intl.Locale(currentLanguage);
55
+ const filteredExt = extensions.filter((ext) => ext.meta.culture.toLowerCase() === locale.baseName.toLowerCase() ||
56
+ ext.meta.culture.toLowerCase() === locale.language.toLowerCase());
57
+ // Only get the extensions that are not already loading/loaded:
58
+ const diff = filteredExt.filter((ext) => !__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadedExtAliases, "f").includes(ext.alias));
59
+ if (diff.length !== 0) {
60
+ // got new localizations to load:
61
+ const translations = await Promise.all(diff.map(__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadExtension, "f")));
62
+ if (translations.length) {
63
+ umbLocalizationManager.registerManyLocalizations(translations);
64
+ // Set the document language
65
+ const newLang = locale.baseName.toLowerCase();
66
+ if (document.documentElement.lang.toLowerCase() !== newLang) {
67
+ document.documentElement.lang = newLang;
68
+ }
69
+ // Set the document direction to the direction of the primary language
70
+ const newDir = translations[0].$dir ?? 'ltr';
71
+ if (document.documentElement.dir !== newDir) {
72
+ document.documentElement.dir = newDir;
73
+ }
74
+ }
72
75
  }
73
76
  });
74
77
  }
@@ -77,12 +80,8 @@ export class UmbLocalizationRegistry {
77
80
  * @param locale The locale to load.
78
81
  */
79
82
  loadLanguage(locale) {
80
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").next(locale);
83
+ __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").setValue(locale.toLowerCase());
81
84
  }
82
85
  }
83
- _UmbLocalizationRegistry_currentLanguage = new WeakMap(), _UmbLocalizationRegistry_isDefaultLoaded = new WeakMap(), _UmbLocalizationRegistry_instances = new WeakSet(), _UmbLocalizationRegistry_addOrUpdateDictionary = function _UmbLocalizationRegistry_addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary) {
84
- for (const [key, value] of Object.entries(dictionary)) {
85
- innerDictionary[`${dictionaryName}_${key}`] = value;
86
- }
87
- };
86
+ _UmbLocalizationRegistry_currentLanguage = new WeakMap(), _UmbLocalizationRegistry_loadedExtAliases = new WeakMap(), _UmbLocalizationRegistry_loadExtension = new WeakMap();
88
87
  export const umbLocalizationRegistry = new UmbLocalizationRegistry(umbExtensionsRegistry);
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { html, nothing, customElement, property } from '../../../../external/lit/index.js';
8
8
  import { UmbLitElement } from '../../../../shared/lit-element/index.js';
9
- import { umbExtensionsRegistry, } from '../../extension-registry/index.js';
9
+ import { umbExtensionsRegistry } from '../../extension-registry/index.js';
10
10
  // TODO: Move to separate file:
11
11
  const manifest = {
12
12
  type: 'kind',
@@ -297,7 +297,7 @@ _UmbDocumentTypeWorkspaceViewEditElement_remove = function _UmbDocumentTypeWorks
297
297
  return;
298
298
  this._workspaceContext?.structure.removeContainer(null, tabId);
299
299
  this._tabsStructureHelper?.isOwnerContainer(tabId)
300
- ? window.history.replaceState(null, '', this._routerPath + this._routes[0]?.path ?? '/root')
300
+ ? window.history.replaceState(null, '', this._routerPath + (this._routes[0]?.path ?? '/root'))
301
301
  : '';
302
302
  };
303
303
  _UmbDocumentTypeWorkspaceViewEditElement_addTab = async function _UmbDocumentTypeWorkspaceViewEditElement_addTab() {
@@ -297,7 +297,7 @@ _UmbMediaTypeWorkspaceViewEditElement_remove = function _UmbMediaTypeWorkspaceVi
297
297
  return;
298
298
  this._workspaceContext?.structure.removeContainer(null, tabId);
299
299
  this._tabsStructureHelper?.isOwnerContainer(tabId)
300
- ? window.history.replaceState(null, '', this._routerPath + this._routes[0]?.path ?? '/root')
300
+ ? window.history.replaceState(null, '', this._routerPath + (this._routes[0]?.path ?? '/root'))
301
301
  : '';
302
302
  };
303
303
  _UmbMediaTypeWorkspaceViewEditElement_addTab = async function _UmbMediaTypeWorkspaceViewEditElement_addTab() {
@@ -30,13 +30,8 @@ export class UmbCurrentUserContext extends UmbBaseController {
30
30
  __classPrivateFieldSet(this, _UmbCurrentUserContext_authContext, instance, "f");
31
31
  __classPrivateFieldGet(this, _UmbCurrentUserContext_instances, "m", _UmbCurrentUserContext_observeIsAuthorized).call(this);
32
32
  });
33
- // TODO: revisit this. It can probably be simplified
34
- this.observe(umbLocalizationRegistry.isDefaultLoaded, (isDefaultLoaded) => {
35
- if (!isDefaultLoaded)
36
- return;
37
- this.observe(this.languageIsoCode, (currentLanguageIsoCode) => {
38
- umbLocalizationRegistry.loadLanguage(currentLanguageIsoCode);
39
- }, 'umbCurrentUserLanguageIsoCode');
33
+ this.observe(this.languageIsoCode, (currentLanguageIsoCode) => {
34
+ umbLocalizationRegistry.loadLanguage(currentLanguageIsoCode);
40
35
  });
41
36
  this.provideContext(UMB_CURRENT_USER_CONTEXT, this);
42
37
  }
@@ -42,14 +42,12 @@ export declare class UmbAuthFlow {
42
42
  * This method will initialize all the state needed for the auth flow.
43
43
  *
44
44
  * It will:
45
- * - Fetch the service configuration from the server
46
45
  * - Check if there is a token response in local storage
47
46
  * - If there is a token response, check if it is valid
48
47
  * - If it is not valid, check if there is a new authorization to be made
49
48
  * - If there is a new authorization to be made, complete it
50
49
  * - If there is no token response, check if there is a new authorization to be made
51
50
  * - If there is a new authorization to be made, complete it
52
- * - If there is no new authorization to be made, do nothing
53
51
  */
54
52
  setInitialState(): Promise<void>;
55
53
  /**
@@ -10,9 +10,24 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _UmbAuthFlow_instances, _UmbAuthFlow_notifier, _UmbAuthFlow_authorizationHandler, _UmbAuthFlow_tokenHandler, _UmbAuthFlow_storageBackend, _UmbAuthFlow_configuration, _UmbAuthFlow_redirectUri, _UmbAuthFlow_clientId, _UmbAuthFlow_scope, _UmbAuthFlow_refreshToken, _UmbAuthFlow_accessTokenResponse, _UmbAuthFlow_saveTokenState, _UmbAuthFlow_makeRefreshTokenRequest;
13
- import { BaseTokenRequestHandler, BasicQueryStringUtils, FetchRequestor, LocalStorageBackend, RedirectRequestHandler, AuthorizationRequest, AuthorizationNotifier, AuthorizationServiceConfiguration, GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN, RevokeTokenRequest, TokenRequest, TokenResponse } from '../../external/openid/index.js';
13
+ /*
14
+ * Copyright 2017 Google Inc.
15
+ *
16
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
17
+ * use this file except in compliance with the License. You may obtain a copy of
18
+ * the License at
19
+ *
20
+ * http://www.apache.org/licenses/LICENSE-2.0
21
+ *
22
+ * Unless required by applicable law or agreed to in writing, software
23
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25
+ * License for the specific language governing permissions and limitations under
26
+ * the License.
27
+ */
28
+ import { UMB_STORAGE_REDIRECT_URL, UMB_STORAGE_TOKEN_RESPONSE_NAME } from './auth.context.token.js';
29
+ import { BaseTokenRequestHandler, BasicQueryStringUtils, FetchRequestor, LocalStorageBackend, RedirectRequestHandler, AuthorizationRequest, AuthorizationNotifier, AuthorizationServiceConfiguration, GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN, RevokeTokenRequest, TokenRequest, TokenResponse, } from '../../external/openid/index.js';
14
30
  const requestor = new FetchRequestor();
15
- const TOKEN_RESPONSE_NAME = 'umb:userAuthTokenResponse';
16
31
  /**
17
32
  * This class is needed to prevent the hash from being parsed as part of the query string.
18
33
  */
@@ -103,6 +118,14 @@ export class UmbAuthFlow {
103
118
  await __classPrivateFieldGet(this, _UmbAuthFlow_instances, "m", _UmbAuthFlow_makeRefreshTokenRequest).call(this, response.code, codeVerifier);
104
119
  await this.performWithFreshTokens();
105
120
  await __classPrivateFieldGet(this, _UmbAuthFlow_instances, "m", _UmbAuthFlow_saveTokenState).call(this);
121
+ // Redirect to the saved state or root
122
+ let currentRoute = '/';
123
+ const savedRoute = sessionStorage.getItem(UMB_STORAGE_REDIRECT_URL);
124
+ if (savedRoute) {
125
+ sessionStorage.removeItem(UMB_STORAGE_REDIRECT_URL);
126
+ currentRoute = savedRoute;
127
+ }
128
+ history.replaceState(null, '', currentRoute);
106
129
  }
107
130
  });
108
131
  }
@@ -110,17 +133,15 @@ export class UmbAuthFlow {
110
133
  * This method will initialize all the state needed for the auth flow.
111
134
  *
112
135
  * It will:
113
- * - Fetch the service configuration from the server
114
136
  * - Check if there is a token response in local storage
115
137
  * - If there is a token response, check if it is valid
116
138
  * - If it is not valid, check if there is a new authorization to be made
117
139
  * - If there is a new authorization to be made, complete it
118
140
  * - If there is no token response, check if there is a new authorization to be made
119
141
  * - If there is a new authorization to be made, complete it
120
- * - If there is no new authorization to be made, do nothing
121
142
  */
122
143
  async setInitialState() {
123
- const tokenResponseJson = await __classPrivateFieldGet(this, _UmbAuthFlow_storageBackend, "f").getItem(TOKEN_RESPONSE_NAME);
144
+ const tokenResponseJson = await __classPrivateFieldGet(this, _UmbAuthFlow_storageBackend, "f").getItem(UMB_STORAGE_TOKEN_RESPONSE_NAME);
124
145
  if (tokenResponseJson) {
125
146
  const response = new TokenResponse(JSON.parse(tokenResponseJson));
126
147
  if (response.isValid()) {
@@ -128,8 +149,6 @@ export class UmbAuthFlow {
128
149
  __classPrivateFieldSet(this, _UmbAuthFlow_refreshToken, __classPrivateFieldGet(this, _UmbAuthFlow_accessTokenResponse, "f").refreshToken, "f");
129
150
  }
130
151
  }
131
- // If no token was found, or if it was invalid, check if there is a new authorization to be made
132
- await this.completeAuthorizationIfPossible();
133
152
  }
134
153
  /**
135
154
  * This method will check if there is a new authorization to be made and complete it if there is.
@@ -174,7 +193,7 @@ export class UmbAuthFlow {
174
193
  * Forget all cached token state
175
194
  */
176
195
  async clearTokenStorage() {
177
- await __classPrivateFieldGet(this, _UmbAuthFlow_storageBackend, "f").removeItem(TOKEN_RESPONSE_NAME);
196
+ await __classPrivateFieldGet(this, _UmbAuthFlow_storageBackend, "f").removeItem(UMB_STORAGE_TOKEN_RESPONSE_NAME);
178
197
  // clear the internal state
179
198
  __classPrivateFieldSet(this, _UmbAuthFlow_accessTokenResponse, undefined, "f");
180
199
  __classPrivateFieldSet(this, _UmbAuthFlow_refreshToken, undefined, "f");
@@ -247,7 +266,7 @@ _UmbAuthFlow_notifier = new WeakMap(), _UmbAuthFlow_authorizationHandler = new W
247
266
  */
248
267
  async function _UmbAuthFlow_saveTokenState() {
249
268
  if (__classPrivateFieldGet(this, _UmbAuthFlow_accessTokenResponse, "f")) {
250
- await __classPrivateFieldGet(this, _UmbAuthFlow_storageBackend, "f").setItem(TOKEN_RESPONSE_NAME, JSON.stringify(__classPrivateFieldGet(this, _UmbAuthFlow_accessTokenResponse, "f").toJson()));
269
+ await __classPrivateFieldGet(this, _UmbAuthFlow_storageBackend, "f").setItem(UMB_STORAGE_TOKEN_RESPONSE_NAME, JSON.stringify(__classPrivateFieldGet(this, _UmbAuthFlow_accessTokenResponse, "f").toJson()));
251
270
  }
252
271
  }, _UmbAuthFlow_makeRefreshTokenRequest =
253
272
  /**
@@ -1,17 +1,20 @@
1
- import type { IUmbAuthContext } from './auth.context.interface.js';
2
1
  import type { UmbControllerHostElement } from '../../libs/controller-api/index.js';
3
2
  import { UmbBaseController } from '../../libs/class-api/index.js';
4
- export declare class UmbAuthContext extends UmbBaseController implements IUmbAuthContext {
3
+ export declare class UmbAuthContext extends UmbBaseController {
5
4
  #private;
6
5
  readonly isAuthorized: import("rxjs").Observable<boolean>;
7
6
  constructor(host: UmbControllerHostElement, serverUrl: string, backofficePath: string, isBypassed: boolean);
8
7
  /**
9
8
  * Initiates the login flow.
10
9
  */
11
- login(): void;
10
+ makeAuthorizationRequest(): void;
11
+ /**
12
+ * Completes the login flow.
13
+ */
14
+ completeAuthorizationRequest(): Promise<void>;
12
15
  /**
13
16
  * Checks if the user is authorized. If Authorization is bypassed, the user is always authorized.
14
- * @returns {boolean} True if the user is authorized, otherwise false.
17
+ * @returns True if the user is authorized, otherwise false.
15
18
  */
16
19
  getIsAuthorized(): boolean;
17
20
  /**
@@ -25,6 +28,13 @@ export declare class UmbAuthContext extends UmbBaseController implements IUmbAut
25
28
  *
26
29
  * NB! The user may experience being redirected to the login screen if the token is expired.
27
30
  *
31
+ * @example
32
+ * ```js
33
+ * const token = await authContext.getLatestToken();
34
+ * const result = await fetch('https://my-api.com', { headers: { Authorization: `Bearer ${token}` } });
35
+ * ```
36
+ *
37
+ * @memberof UmbAuthContext
28
38
  * @returns The latest token from the Management API
29
39
  */
30
40
  getLatestToken(): Promise<string>;
@@ -35,7 +45,6 @@ export declare class UmbAuthContext extends UmbBaseController implements IUmbAut
35
45
  clearTokenStorage(): Promise<void>;
36
46
  /**
37
47
  * Signs the user out by removing any tokens from the browser.
38
- * @return {*} {Promise<void>}
39
48
  * @memberof UmbAuthContext
40
49
  */
41
50
  signOut(): Promise<void>;
@@ -31,12 +31,18 @@ export class UmbAuthContext extends UmbBaseController {
31
31
  /**
32
32
  * Initiates the login flow.
33
33
  */
34
- login() {
34
+ makeAuthorizationRequest() {
35
35
  return __classPrivateFieldGet(this, _UmbAuthContext_authFlow, "f").makeAuthorizationRequest();
36
36
  }
37
+ /**
38
+ * Completes the login flow.
39
+ */
40
+ completeAuthorizationRequest() {
41
+ return __classPrivateFieldGet(this, _UmbAuthContext_authFlow, "f").completeAuthorizationIfPossible();
42
+ }
37
43
  /**
38
44
  * Checks if the user is authorized. If Authorization is bypassed, the user is always authorized.
39
- * @returns {boolean} True if the user is authorized, otherwise false.
45
+ * @returns True if the user is authorized, otherwise false.
40
46
  */
41
47
  getIsAuthorized() {
42
48
  if (__classPrivateFieldGet(this, _UmbAuthContext_isBypassed, "f")) {
@@ -62,6 +68,13 @@ export class UmbAuthContext extends UmbBaseController {
62
68
  *
63
69
  * NB! The user may experience being redirected to the login screen if the token is expired.
64
70
  *
71
+ * @example
72
+ * ```js
73
+ * const token = await authContext.getLatestToken();
74
+ * const result = await fetch('https://my-api.com', { headers: { Authorization: `Bearer ${token}` } });
75
+ * ```
76
+ *
77
+ * @memberof UmbAuthContext
65
78
  * @returns The latest token from the Management API
66
79
  */
67
80
  getLatestToken() {
@@ -76,7 +89,6 @@ export class UmbAuthContext extends UmbBaseController {
76
89
  }
77
90
  /**
78
91
  * Signs the user out by removing any tokens from the browser.
79
- * @return {*} {Promise<void>}
80
92
  * @memberof UmbAuthContext
81
93
  */
82
94
  signOut() {
@@ -1,3 +1,5 @@
1
- import type { IUmbAuthContext } from './auth.context.interface.js';
1
+ import type { UmbAuthContext } from './auth.context.js';
2
2
  import { UmbContextToken } from '../../libs/context-api/index.js';
3
- export declare const UMB_AUTH_CONTEXT: UmbContextToken<IUmbAuthContext, IUmbAuthContext>;
3
+ export declare const UMB_AUTH_CONTEXT: UmbContextToken<UmbAuthContext, UmbAuthContext>;
4
+ export declare const UMB_STORAGE_TOKEN_RESPONSE_NAME = "umb:userAuthTokenResponse";
5
+ export declare const UMB_STORAGE_REDIRECT_URL = "umb:auth:redirect";
@@ -1,2 +1,4 @@
1
1
  import { UmbContextToken } from '../../libs/context-api/index.js';
2
2
  export const UMB_AUTH_CONTEXT = new UmbContextToken('UmbAuthContext');
3
+ export const UMB_STORAGE_TOKEN_RESPONSE_NAME = 'umb:userAuthTokenResponse';
4
+ export const UMB_STORAGE_REDIRECT_URL = 'umb:auth:redirect';
@@ -1,3 +1,2 @@
1
- export * from './auth.context.interface.js';
2
1
  export * from './auth.context.js';
3
2
  export * from './auth.context.token.js';
@@ -1,3 +1,2 @@
1
- export * from './auth.context.interface.js';
2
1
  export * from './auth.context.js';
3
2
  export * from './auth.context.token.js';