@theia/core 1.53.0-next.55 → 1.53.0-next.64
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/README.md +6 -6
- package/i18n/nls.cs.json +582 -582
- package/i18n/nls.de.json +582 -582
- package/i18n/nls.es.json +582 -582
- package/i18n/nls.fr.json +582 -582
- package/i18n/nls.hu.json +582 -582
- package/i18n/nls.it.json +582 -582
- package/i18n/nls.ja.json +582 -582
- package/i18n/nls.json +582 -582
- package/i18n/nls.ko.json +582 -582
- package/i18n/nls.pl.json +582 -582
- package/i18n/nls.pt-br.json +582 -582
- package/i18n/nls.ru.json +582 -582
- package/i18n/nls.tr.json +582 -582
- package/i18n/nls.zh-cn.json +582 -582
- package/i18n/nls.zh-tw.json +582 -582
- package/lib/browser/catalog.json +54 -6
- package/lib/browser/common-frontend-contribution.js +3 -3
- package/lib/browser/common-styling-participants.js +166 -166
- package/lib/browser/progress-location-service.spec.js +7 -7
- package/lib/browser/storage-service.js +3 -3
- package/lib/browser/tree/tree.spec.js +75 -75
- package/lib/node/process-utils.spec.js +8 -8
- package/package.json +4 -4
- package/shared/ajv/index.d.ts +2 -2
- package/shared/markdown-it.d.ts +2 -2
- package/shared/markdown-it.js +1 -1
- package/shared/reflect-metadata/index.d.ts +1 -1
- package/shared/reflect-metadata/index.js +1 -1
- package/shared/vscode-languageserver-types/index.d.ts +1 -1
- package/src/browser/about-dialog.tsx +137 -137
- package/src/browser/authentication-service.ts +467 -467
- package/src/browser/breadcrumbs/breadcrumb-popup-container.ts +101 -101
- package/src/browser/breadcrumbs/breadcrumb-renderer.tsx +41 -41
- package/src/browser/breadcrumbs/breadcrumbs-constants.ts +79 -79
- package/src/browser/breadcrumbs/breadcrumbs-renderer.tsx +185 -185
- package/src/browser/breadcrumbs/breadcrumbs-service.ts +108 -108
- package/src/browser/breadcrumbs/index.ts +21 -21
- package/src/browser/browser-clipboard-service.ts +122 -122
- package/src/browser/browser.ts +239 -239
- package/src/browser/clipboard-service.ts +23 -23
- package/src/browser/color-application-contribution.ts +110 -110
- package/src/browser/color-registry.ts +60 -60
- package/src/browser/command-open-handler.ts +54 -54
- package/src/browser/common-frontend-contribution.ts +2680 -2680
- package/src/browser/common-styling-participants.ts +361 -361
- package/src/browser/connection-status-service.spec.ts +200 -200
- package/src/browser/connection-status-service.ts +216 -216
- package/src/browser/context-key-service.ts +142 -142
- package/src/browser/context-menu-renderer.ts +124 -124
- package/src/browser/core-preferences.ts +343 -343
- package/src/browser/credentials-service.ts +106 -106
- package/src/browser/decoration-style.ts +65 -65
- package/src/browser/decorations-service.ts +209 -209
- package/src/browser/dialogs/react-dialog.tsx +56 -56
- package/src/browser/dialogs.ts +534 -534
- package/src/browser/diff-uris.ts +117 -117
- package/src/browser/encoding-registry.ts +97 -97
- package/src/browser/endpoint.spec.ts +148 -148
- package/src/browser/endpoint.ts +136 -136
- package/src/browser/external-uri-service.ts +79 -79
- package/src/browser/file-icons-js.d.ts +20 -20
- package/src/browser/frontend-application-bindings.ts +62 -62
- package/src/browser/frontend-application-config-provider.spec.ts +45 -45
- package/src/browser/frontend-application-config-provider.ts +50 -50
- package/src/browser/frontend-application-contribution.ts +110 -110
- package/src/browser/frontend-application-module.ts +474 -474
- package/src/browser/frontend-application-state.ts +74 -74
- package/src/browser/frontend-application.ts +326 -326
- package/src/browser/hover-service.ts +218 -218
- package/src/browser/http-open-handler.ts +49 -49
- package/src/browser/i18n/i18n-frontend-module.ts +27 -27
- package/src/browser/i18n/language-quick-pick-service.ts +130 -130
- package/src/browser/icon-registry.ts +87 -87
- package/src/browser/icon-theme-contribution.ts +64 -64
- package/src/browser/icon-theme-service.ts +217 -217
- package/src/browser/icons/CollapseAll.svg +7 -7
- package/src/browser/icons/CollapseAll_inverse.svg +7 -7
- package/src/browser/icons/Refresh.svg +7 -7
- package/src/browser/icons/Refresh_inverse.svg +7 -7
- package/src/browser/icons/add-inverse.svg +4 -4
- package/src/browser/icons/add.svg +4 -4
- package/src/browser/icons/arrow-down-bright.svg +6 -6
- package/src/browser/icons/arrow-down-dark.svg +6 -6
- package/src/browser/icons/arrow-up-bright.svg +6 -6
- package/src/browser/icons/arrow-up-dark.svg +6 -6
- package/src/browser/icons/case-sensitive-dark.svg +16 -16
- package/src/browser/icons/case-sensitive.svg +16 -16
- package/src/browser/icons/chevron-right-dark.svg +5 -5
- package/src/browser/icons/chevron-right-light.svg +6 -6
- package/src/browser/icons/circle-bright.svg +7 -7
- package/src/browser/icons/circle-dark.svg +7 -7
- package/src/browser/icons/clear-search-results-dark.svg +7 -7
- package/src/browser/icons/clear-search-results.svg +7 -7
- package/src/browser/icons/close-all-bright.svg +7 -7
- package/src/browser/icons/close-all-dark.svg +7 -7
- package/src/browser/icons/close-bright.svg +7 -7
- package/src/browser/icons/close-dark.svg +7 -7
- package/src/browser/icons/collapse.svg +4 -4
- package/src/browser/icons/edit-json-dark.svg +6 -6
- package/src/browser/icons/edit-json.svg +6 -6
- package/src/browser/icons/expand.svg +4 -4
- package/src/browser/icons/loading-dark.svg +6 -6
- package/src/browser/icons/loading-light.svg +6 -6
- package/src/browser/icons/open-change-bright.svg +3 -3
- package/src/browser/icons/open-change-dark.svg +4 -4
- package/src/browser/icons/open-file-bright.svg +4 -4
- package/src/browser/icons/open-file-dark.svg +4 -4
- package/src/browser/icons/preview-bright.svg +3 -3
- package/src/browser/icons/preview-dark.svg +3 -3
- package/src/browser/icons/regex-dark.svg +10 -10
- package/src/browser/icons/regex.svg +10 -10
- package/src/browser/icons/remove-all-inverse.svg +4 -4
- package/src/browser/icons/remove-all.svg +4 -4
- package/src/browser/icons/replace-all-inverse.svg +13 -13
- package/src/browser/icons/replace-all.svg +13 -13
- package/src/browser/icons/replace-inverse.svg +15 -15
- package/src/browser/icons/replace.svg +15 -15
- package/src/browser/icons/whole-word-dark.svg +19 -19
- package/src/browser/icons/whole-word.svg +19 -19
- package/src/browser/index.ts +50 -50
- package/src/browser/json-schema-store.ts +118 -118
- package/src/browser/keybinding.spec.ts +554 -554
- package/src/browser/keybinding.ts +759 -759
- package/src/browser/keyboard/browser-keyboard-frontend-contribution.ts +108 -108
- package/src/browser/keyboard/browser-keyboard-layout-provider.spec.ts +171 -171
- package/src/browser/keyboard/browser-keyboard-layout-provider.ts +469 -469
- package/src/browser/keyboard/browser-keyboard-module.ts +30 -30
- package/src/browser/keyboard/index.ts +20 -20
- package/src/browser/keyboard/keyboard-layout-service.spec.ts +121 -121
- package/src/browser/keyboard/keyboard-layout-service.ts +455 -455
- package/src/browser/keyboard/keys.spec.ts +258 -258
- package/src/browser/keyboard/keys.ts +20 -20
- package/src/browser/keys.ts +21 -21
- package/src/browser/label-parser.spec.ts +165 -165
- package/src/browser/label-parser.ts +108 -108
- package/src/browser/label-provider.spec.ts +62 -62
- package/src/browser/label-provider.ts +385 -385
- package/src/browser/language-icon-provider.ts +55 -55
- package/src/browser/language-service.ts +77 -77
- package/src/browser/logger-frontend-module.ts +65 -65
- package/src/browser/markdown-rendering/markdown-renderer.ts +98 -98
- package/src/browser/menu/browser-context-menu-renderer.ts +48 -48
- package/src/browser/menu/browser-menu-module.ts +28 -28
- package/src/browser/menu/browser-menu-plugin.ts +491 -491
- package/src/browser/menu/context-menu-context.ts +41 -41
- package/src/browser/messaging/connection-source.ts +26 -26
- package/src/browser/messaging/frontend-id-provider.ts +37 -37
- package/src/browser/messaging/index.ts +18 -18
- package/src/browser/messaging/messaging-frontend-module.ts +41 -41
- package/src/browser/messaging/service-connection-provider.ts +140 -140
- package/src/browser/messaging/ws-connection-provider.ts +49 -49
- package/src/browser/messaging/ws-connection-source.ts +230 -230
- package/src/browser/mime-service.ts +30 -30
- package/src/browser/navigatable-types.ts +81 -81
- package/src/browser/navigatable.ts +39 -39
- package/src/browser/open-with-service.ts +140 -140
- package/src/browser/opener-service.spec.ts +49 -49
- package/src/browser/opener-service.ts +169 -169
- package/src/browser/performance/frontend-stopwatch.ts +65 -65
- package/src/browser/performance/index.ts +18 -18
- package/src/browser/performance/measurement-frontend-bindings.ts +31 -31
- package/src/browser/preferences/index.ts +23 -23
- package/src/browser/preferences/injectable-preference-proxy.ts +283 -283
- package/src/browser/preferences/preference-configurations.ts +82 -82
- package/src/browser/preferences/preference-contribution.ts +436 -436
- package/src/browser/preferences/preference-language-override-service.ts +111 -111
- package/src/browser/preferences/preference-provider.spec.ts +36 -36
- package/src/browser/preferences/preference-provider.ts +277 -277
- package/src/browser/preferences/preference-proxy.spec.ts +367 -367
- package/src/browser/preferences/preference-proxy.ts +367 -367
- package/src/browser/preferences/preference-schema-provider.spec.ts +130 -130
- package/src/browser/preferences/preference-scope.ts +18 -18
- package/src/browser/preferences/preference-service.spec.ts +613 -613
- package/src/browser/preferences/preference-service.ts +594 -594
- package/src/browser/preferences/preference-validation-service.spec.ts +334 -334
- package/src/browser/preferences/preference-validation-service.ts +358 -358
- package/src/browser/preferences/test/index.ts +19 -19
- package/src/browser/preferences/test/mock-preference-provider.ts +50 -50
- package/src/browser/preferences/test/mock-preference-proxy.ts +48 -48
- package/src/browser/preferences/test/mock-preference-service.ts +63 -63
- package/src/browser/preload/i18n-preload-contribution.ts +50 -50
- package/src/browser/preload/os-preload-contribution.ts +37 -37
- package/src/browser/preload/preload-module.ts +45 -45
- package/src/browser/preload/preloader.ts +37 -37
- package/src/browser/preload/theme-preload-contribution.ts +31 -31
- package/src/browser/progress-bar-factory.ts +29 -29
- package/src/browser/progress-bar.ts +76 -76
- package/src/browser/progress-client.ts +53 -53
- package/src/browser/progress-location-service.spec.ts +50 -50
- package/src/browser/progress-location-service.ts +96 -96
- package/src/browser/progress-status-bar-item.ts +83 -83
- package/src/browser/quick-input/index.ts +23 -23
- package/src/browser/quick-input/quick-access.ts +75 -75
- package/src/browser/quick-input/quick-command-frontend-contribution.ts +89 -89
- package/src/browser/quick-input/quick-command-service.ts +246 -246
- package/src/browser/quick-input/quick-help-service.ts +87 -87
- package/src/browser/quick-input/quick-input-frontend-contribution.ts +33 -33
- package/src/browser/quick-input/quick-input-service.spec.ts +176 -176
- package/src/browser/quick-input/quick-input-service.ts +17 -17
- package/src/browser/quick-input/quick-pick-service-impl.ts +69 -69
- package/src/browser/quick-input/quick-view-service.ts +83 -83
- package/src/browser/request/browser-request-module.ts +23 -23
- package/src/browser/request/browser-request-service.ts +172 -172
- package/src/browser/resource-context-key.ts +77 -77
- package/src/browser/saveable-service.ts +332 -332
- package/src/browser/saveable.ts +395 -395
- package/src/browser/secondary-window-handler.ts +211 -211
- package/src/browser/shell/additional-views-menu-widget.tsx +71 -71
- package/src/browser/shell/application-shell-mouse-tracker.ts +103 -103
- package/src/browser/shell/application-shell.ts +2271 -2271
- package/src/browser/shell/current-widget-command-adapter.ts +57 -57
- package/src/browser/shell/index.ts +23 -23
- package/src/browser/shell/shell-layout-restorer.ts +399 -399
- package/src/browser/shell/side-panel-handler.ts +794 -794
- package/src/browser/shell/side-panel-toolbar.ts +111 -111
- package/src/browser/shell/sidebar-bottom-menu-widget.tsx +39 -39
- package/src/browser/shell/sidebar-menu-widget.tsx +183 -183
- package/src/browser/shell/sidebar-top-menu-widget.tsx +26 -26
- package/src/browser/shell/split-panels.ts +191 -191
- package/src/browser/shell/tab-bar-decorator.ts +106 -106
- package/src/browser/shell/tab-bar-toolbar/index.ts +19 -19
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.ts +31 -31
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +242 -242
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.ts +149 -149
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.ts +62 -62
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +443 -443
- package/src/browser/shell/tab-bars.spec.ts +63 -63
- package/src/browser/shell/tab-bars.ts +1468 -1468
- package/src/browser/shell/theia-dock-panel.ts +265 -265
- package/src/browser/shell/view-column-service.ts +125 -125
- package/src/browser/shell/view-contribution.ts +178 -178
- package/src/browser/source-tree/index.ts +19 -19
- package/src/browser/source-tree/source-tree-widget.tsx +107 -107
- package/src/browser/source-tree/source-tree.ts +146 -146
- package/src/browser/source-tree/tree-source.ts +73 -73
- package/src/browser/status-bar/index.ts +29 -29
- package/src/browser/status-bar/status-bar-types.ts +97 -97
- package/src/browser/status-bar/status-bar-view-model.ts +209 -209
- package/src/browser/status-bar/status-bar.tsx +189 -189
- package/src/browser/storage-service.spec.ts +76 -76
- package/src/browser/storage-service.ts +129 -129
- package/src/browser/style/about.css +36 -36
- package/src/browser/style/alert-messages.css +62 -62
- package/src/browser/style/ansi.css +88 -88
- package/src/browser/style/breadcrumbs.css +130 -130
- package/src/browser/style/dialog.css +126 -126
- package/src/browser/style/dockpanel.css +76 -76
- package/src/browser/style/hover-service.css +101 -101
- package/src/browser/style/icons.css +61 -61
- package/src/browser/style/index.css +353 -353
- package/src/browser/style/materialcolors.css +278 -278
- package/src/browser/style/menus.css +230 -230
- package/src/browser/style/notification.css +39 -39
- package/src/browser/style/os.css +87 -87
- package/src/browser/style/progress-bar.css +43 -43
- package/src/browser/style/quick-title-bar.css +45 -45
- package/src/browser/style/scrollbars.css +172 -172
- package/src/browser/style/search-box.css +123 -123
- package/src/browser/style/select-component.css +107 -107
- package/src/browser/style/sidepanel.css +367 -367
- package/src/browser/style/split-widget.css +38 -38
- package/src/browser/style/status-bar.css +127 -127
- package/src/browser/style/tabs.css +647 -647
- package/src/browser/style/tooltip.css +28 -28
- package/src/browser/style/tree-decorators.css +81 -81
- package/src/browser/style/tree.css +232 -232
- package/src/browser/style/view-container.css +187 -187
- package/src/browser/style/widget.css +19 -19
- package/src/browser/styling-service.ts +96 -96
- package/src/browser/supported-encodings.ts +262 -262
- package/src/browser/test/jsdom.ts +69 -69
- package/src/browser/test/mock-connection-status-service.ts +33 -33
- package/src/browser/test/mock-env-variables-server.ts +47 -47
- package/src/browser/test/mock-opener-service.ts +34 -34
- package/src/browser/test/mock-storage-service.ts +49 -49
- package/src/browser/theming.ts +206 -206
- package/src/browser/tooltip-service.tsx +96 -96
- package/src/browser/tree/fuzzy-search.spec.ts +99 -99
- package/src/browser/tree/fuzzy-search.ts +136 -136
- package/src/browser/tree/index.ts +29 -29
- package/src/browser/tree/search-box-debounce.ts +96 -96
- package/src/browser/tree/search-box.ts +355 -355
- package/src/browser/tree/test/mock-selectable-tree-model.ts +109 -109
- package/src/browser/tree/test/mock-tree-model.ts +136 -136
- package/src/browser/tree/test/tree-test-container.ts +50 -50
- package/src/browser/tree/tree-compression/compressed-tree-expansion-service.ts +46 -46
- package/src/browser/tree/tree-compression/compressed-tree-model.ts +88 -88
- package/src/browser/tree/tree-compression/compressed-tree-widget.tsx +203 -203
- package/src/browser/tree/tree-compression/index.ts +20 -20
- package/src/browser/tree/tree-compression/tree-compression-service.ts +125 -125
- package/src/browser/tree/tree-compression/tree-compression.css +28 -28
- package/src/browser/tree/tree-consistency.spec.ts +105 -105
- package/src/browser/tree/tree-container.spec.ts +45 -45
- package/src/browser/tree/tree-container.ts +155 -155
- package/src/browser/tree/tree-decorator.spec.ts +162 -162
- package/src/browser/tree/tree-decorator.ts +238 -238
- package/src/browser/tree/tree-expansion.spec.ts +173 -173
- package/src/browser/tree/tree-expansion.ts +165 -165
- package/src/browser/tree/tree-focus-service.ts +55 -55
- package/src/browser/tree/tree-iterator.spec.ts +170 -170
- package/src/browser/tree/tree-iterator.ts +256 -256
- package/src/browser/tree/tree-label-provider.ts +40 -40
- package/src/browser/tree/tree-model.ts +562 -562
- package/src/browser/tree/tree-navigation.ts +58 -58
- package/src/browser/tree/tree-preference.ts +50 -50
- package/src/browser/tree/tree-search.ts +128 -128
- package/src/browser/tree/tree-selectable.spec.ts +152 -152
- package/src/browser/tree/tree-selection-impl.ts +176 -176
- package/src/browser/tree/tree-selection-state.spec.ts +462 -462
- package/src/browser/tree/tree-selection-state.ts +245 -245
- package/src/browser/tree/tree-selection.ts +159 -159
- package/src/browser/tree/tree-view-welcome-widget.tsx +263 -263
- package/src/browser/tree/tree-widget-selection.ts +45 -45
- package/src/browser/tree/tree-widget.tsx +1591 -1591
- package/src/browser/tree/tree.spec.ts +241 -241
- package/src/browser/tree/tree.ts +425 -425
- package/src/browser/undo-redo-handler.ts +85 -85
- package/src/browser/user-working-directory-provider.ts +77 -77
- package/src/browser/view-container.ts +1640 -1640
- package/src/browser/widget-decoration.ts +358 -358
- package/src/browser/widget-manager.spec.ts +102 -102
- package/src/browser/widget-manager.ts +318 -318
- package/src/browser/widget-open-handler.ts +168 -168
- package/src/browser/widgets/alert-message.tsx +56 -56
- package/src/browser/widgets/enhanced-preview-widget.ts +27 -27
- package/src/browser/widgets/extractable-widget.ts +33 -33
- package/src/browser/widgets/index.ts +21 -21
- package/src/browser/widgets/previewable-widget.ts +31 -31
- package/src/browser/widgets/react-renderer.tsx +53 -53
- package/src/browser/widgets/react-widget.tsx +51 -51
- package/src/browser/widgets/select-component.tsx +367 -367
- package/src/browser/widgets/split-widget.ts +163 -163
- package/src/browser/widgets/widget.ts +406 -406
- package/src/browser/window/browser-window-module.ts +32 -32
- package/src/browser/window/default-secondary-window-service.ts +189 -189
- package/src/browser/window/default-window-service.spec.ts +78 -78
- package/src/browser/window/default-window-service.ts +171 -171
- package/src/browser/window/secondary-window-service.ts +39 -39
- package/src/browser/window/test/mock-window-service.ts +29 -29
- package/src/browser/window/window-service.ts +78 -78
- package/src/browser/window/window-title-service.ts +107 -107
- package/src/browser/window/window-title-updater.ts +95 -95
- package/src/browser/window-contribution.ts +64 -64
- package/src/browser-only/frontend-only-application-module.ts +116 -116
- package/src/browser-only/i18n/i18n-frontend-only-module.ts +37 -37
- package/src/browser-only/logger-frontend-only-module.ts +63 -63
- package/src/browser-only/messaging/frontend-only-service-connection-provider.ts +39 -39
- package/src/browser-only/messaging/messaging-frontend-only-module.ts +42 -42
- package/src/browser-only/preload/frontend-only-preload-module.ts +49 -49
- package/src/common/accessibility.ts +33 -33
- package/src/common/application-error.spec.ts +27 -27
- package/src/common/application-error.ts +76 -76
- package/src/common/application-protocol.ts +42 -42
- package/src/common/array-utils.ts +129 -129
- package/src/common/buffer.ts +228 -228
- package/src/common/cancellation.ts +163 -163
- package/src/common/char-code.ts +438 -438
- package/src/common/collections.ts +125 -125
- package/src/common/color.ts +103 -103
- package/src/common/command.spec.ts +208 -208
- package/src/common/command.ts +489 -489
- package/src/common/contribution-filter/contribution-filter-registry.ts +79 -79
- package/src/common/contribution-filter/contribution-filter.ts +64 -64
- package/src/common/contribution-filter/filter.ts +23 -23
- package/src/common/contribution-filter/index.ts +19 -19
- package/src/common/contribution-provider.ts +96 -96
- package/src/common/disposable.spec.ts +94 -94
- package/src/common/disposable.ts +188 -188
- package/src/common/encoding-service.ts +380 -380
- package/src/common/encodings.ts +24 -24
- package/src/common/env-variables/env-variables-protocol.ts +38 -38
- package/src/common/env-variables/index.ts +17 -17
- package/src/common/event.spec.ts +32 -32
- package/src/common/event.ts +493 -493
- package/src/common/file-uri.ts +61 -61
- package/src/common/frontend-application-state.ts +38 -38
- package/src/common/glob.ts +741 -741
- package/src/common/hash.ts +85 -85
- package/src/common/i18n/localization-server.ts +25 -25
- package/src/common/i18n/localization.ts +80 -80
- package/src/common/i18n/nls.metadata.json +34112 -34112
- package/src/common/index.ts +51 -51
- package/src/common/json-schema.ts +108 -108
- package/src/common/key-store.ts +26 -26
- package/src/common/keybinding.ts +152 -152
- package/src/common/keyboard/keyboard-layout-provider.ts +51 -51
- package/src/common/keys.ts +694 -694
- package/src/common/label-protocol.ts +35 -35
- package/src/common/logger-protocol.ts +119 -119
- package/src/common/logger-watcher.ts +48 -48
- package/src/common/logger.spec.ts +46 -46
- package/src/common/logger.ts +389 -389
- package/src/common/lsp-types.ts +34 -34
- package/src/common/markdown-rendering/icon-utilities.ts +30 -30
- package/src/common/markdown-rendering/index.ts +18 -18
- package/src/common/markdown-rendering/markdown-string.ts +152 -152
- package/src/common/menu/action-menu-node.ts +65 -65
- package/src/common/menu/composite-menu-node.spec.ts +67 -67
- package/src/common/menu/composite-menu-node.ts +114 -114
- package/src/common/menu/index.ts +21 -21
- package/src/common/menu/menu-adapter.ts +103 -103
- package/src/common/menu/menu-model-registry.ts +374 -374
- package/src/common/menu/menu-types.ts +220 -220
- package/src/common/menu/menu.spec.ts +101 -101
- package/src/common/message-rpc/channel.spec.ts +88 -88
- package/src/common/message-rpc/channel.ts +300 -300
- package/src/common/message-rpc/index.ts +22 -22
- package/src/common/message-rpc/message-buffer.ts +105 -105
- package/src/common/message-rpc/msg-pack-extension-manager.ts +70 -70
- package/src/common/message-rpc/rpc-message-encoder.spec.ts +65 -65
- package/src/common/message-rpc/rpc-message-encoder.ts +190 -190
- package/src/common/message-rpc/rpc-protocol.ts +255 -255
- package/src/common/message-rpc/uint8-array-message-buffer.spec.ts +41 -41
- package/src/common/message-rpc/uint8-array-message-buffer.ts +213 -213
- package/src/common/message-service-protocol.ts +148 -148
- package/src/common/message-service.ts +226 -226
- package/src/common/messaging/connection-error-handler.ts +73 -73
- package/src/common/messaging/connection-management.ts +43 -43
- package/src/common/messaging/handler.ts +26 -26
- package/src/common/messaging/index.ts +19 -19
- package/src/common/messaging/proxy-factory.spec.ts +108 -108
- package/src/common/messaging/proxy-factory.ts +336 -336
- package/src/common/messaging/socket-write-buffer.ts +52 -52
- package/src/common/messaging/web-socket-channel.ts +76 -76
- package/src/common/nls.ts +151 -151
- package/src/common/numbers.ts +21 -21
- package/src/common/objects.spec.ts +112 -112
- package/src/common/objects.ts +123 -123
- package/src/common/os.ts +82 -82
- package/src/common/path.spec.ts +415 -415
- package/src/common/path.ts +334 -334
- package/src/common/paths.ts +250 -250
- package/src/common/performance/index.ts +19 -19
- package/src/common/performance/measurement-protocol.ts +104 -104
- package/src/common/performance/measurement.ts +130 -130
- package/src/common/performance/stopwatch.ts +183 -183
- package/src/common/preferences/preference-schema.ts +101 -101
- package/src/common/preferences/preference-scope.spec.ts +48 -48
- package/src/common/preferences/preference-scope.ts +68 -68
- package/src/common/prioritizeable.ts +58 -58
- package/src/common/progress-service-protocol.ts +35 -35
- package/src/common/progress-service.ts +82 -82
- package/src/common/promise-util.spec.ts +102 -102
- package/src/common/promise-util.ts +143 -143
- package/src/common/quick-pick-service.ts +353 -353
- package/src/common/reference.spec.ts +145 -145
- package/src/common/reference.ts +230 -230
- package/src/common/resource.ts +430 -430
- package/src/common/selection-command-handler.ts +101 -101
- package/src/common/selection-service.spec.ts +43 -43
- package/src/common/selection-service.ts +49 -49
- package/src/common/selection.ts +50 -50
- package/src/common/severity.ts +111 -111
- package/src/common/stream.ts +718 -718
- package/src/common/strings.ts +231 -231
- package/src/common/telemetry.ts +45 -45
- package/src/common/ternary-search-tree.ts +417 -417
- package/src/common/test/expect.ts +34 -34
- package/src/common/test/mock-logger.ts +118 -118
- package/src/common/test/mock-menu.ts +35 -35
- package/src/common/test/mock-resource-provider.ts +33 -33
- package/src/common/theme.ts +68 -68
- package/src/common/types.spec.ts +86 -86
- package/src/common/types.ts +140 -140
- package/src/common/uri-command-handler.spec.ts +90 -90
- package/src/common/uri-command-handler.ts +148 -148
- package/src/common/uri.spec.ts +278 -278
- package/src/common/uri.ts +279 -279
- package/src/common/uuid.ts +45 -45
- package/src/common/version.ts +17 -17
- package/src/common/view-column.ts +33 -33
- package/src/common/window.ts +34 -34
- package/src/electron-browser/electron-clipboard-service.ts +32 -32
- package/src/electron-browser/electron-uri-handler.ts +42 -42
- package/src/electron-browser/keyboard/electron-keyboard-layout-change-notifier.ts +39 -39
- package/src/electron-browser/keyboard/electron-keyboard-module.ts +28 -28
- package/src/electron-browser/menu/electron-context-menu-renderer.ts +122 -122
- package/src/electron-browser/menu/electron-main-menu-factory.ts +339 -339
- package/src/electron-browser/menu/electron-menu-contribution.ts +506 -506
- package/src/electron-browser/menu/electron-menu-module.ts +40 -40
- package/src/electron-browser/menu/electron-menu-style.css +110 -110
- package/src/electron-browser/messaging/electron-frontend-id-provider.ts +25 -25
- package/src/electron-browser/messaging/electron-ipc-connection-source.ts +65 -65
- package/src/electron-browser/messaging/electron-local-ws-connection-source.ts +45 -45
- package/src/electron-browser/messaging/electron-messaging-frontend-module.ts +78 -78
- package/src/electron-browser/messaging/electron-ws-connection-source.ts +38 -38
- package/src/electron-browser/preload.ts +264 -264
- package/src/electron-browser/request/electron-browser-request-module.ts +26 -26
- package/src/electron-browser/token/electron-token-frontend-module.ts +22 -22
- package/src/electron-browser/window/electron-frontend-application-state.ts +26 -26
- package/src/electron-browser/window/electron-secondary-window-service.ts +35 -35
- package/src/electron-browser/window/electron-window-module.ts +48 -48
- package/src/electron-browser/window/electron-window-preferences.ts +76 -76
- package/src/electron-browser/window/electron-window-service.ts +109 -109
- package/src/electron-browser/window/external-app-open-handler.ts +42 -42
- package/src/electron-common/electron-api.ts +157 -157
- package/src/electron-common/electron-main-window-service.ts +24 -24
- package/src/electron-common/electron-token.ts +27 -27
- package/src/electron-main/electron-api-main.ts +373 -373
- package/src/electron-main/electron-main-application-module.ts +65 -65
- package/src/electron-main/electron-main-application.ts +860 -860
- package/src/electron-main/electron-main-constants.ts +23 -23
- package/src/electron-main/electron-main-window-service-impl.ts +44 -44
- package/src/electron-main/electron-security-token-service.ts +36 -36
- package/src/electron-main/event-utils.ts +36 -36
- package/src/electron-main/messaging/electron-connection-handler.ts +21 -21
- package/src/electron-main/messaging/electron-messaging-contribution.ts +143 -143
- package/src/electron-main/messaging/electron-messaging-service.ts +35 -35
- package/src/electron-main/theia-electron-window.ts +219 -219
- package/src/electron-node/cli/electron-backend-cli-module.ts +24 -24
- package/src/electron-node/cli/electron-cli-contribution.ts +35 -35
- package/src/electron-node/hosting/electron-backend-hosting-module.ts +24 -24
- package/src/electron-node/hosting/electron-ws-origin-validator.ts +37 -37
- package/src/electron-node/keyboard/electron-backend-keyboard-module.ts +30 -30
- package/src/electron-node/keyboard/electron-keyboard-layout-provider.ts +35 -35
- package/src/electron-node/request/electron-backend-request-module.ts +23 -23
- package/src/electron-node/request/electron-backend-request-service.ts +78 -78
- package/src/electron-node/token/electron-token-backend-contribution.ts +48 -48
- package/src/electron-node/token/electron-token-backend-module.ts +28 -28
- package/src/electron-node/token/electron-token-validator.ts +93 -93
- package/src/node/application-server.ts +59 -59
- package/src/node/backend-application-config-provider.spec.ts +29 -29
- package/src/node/backend-application-config-provider.ts +48 -48
- package/src/node/backend-application-module.ts +139 -139
- package/src/node/backend-application.ts +374 -374
- package/src/node/cli.spec.ts +94 -94
- package/src/node/cli.ts +63 -63
- package/src/node/console-logger-server.spec.ts +59 -59
- package/src/node/console-logger-server.ts +76 -76
- package/src/node/debug.ts +30 -30
- package/src/node/dynamic-require.ts +56 -56
- package/src/node/env-variables/env-variables-server.ts +123 -123
- package/src/node/env-variables/index.ts +17 -17
- package/src/node/environment-utils.spec.ts +92 -92
- package/src/node/environment-utils.ts +66 -66
- package/src/node/file-uri.spec.ts +76 -76
- package/src/node/filesystem-locking.ts +77 -77
- package/src/node/hosting/backend-application-hosts.ts +60 -60
- package/src/node/hosting/backend-hosting-module.ts +26 -26
- package/src/node/hosting/ws-origin-validator.ts +36 -36
- package/src/node/i18n/i18n-backend-module.ts +42 -42
- package/src/node/i18n/localization-contribution.ts +112 -112
- package/src/node/i18n/localization-provider.ts +125 -125
- package/src/node/i18n/localization-server.ts +52 -52
- package/src/node/i18n/theia-localization-contribution.ts +40 -40
- package/src/node/index.ts +22 -22
- package/src/node/key-store-server.ts +162 -162
- package/src/node/logger-backend-module.ts +88 -88
- package/src/node/logger-cli-contribution.spec.ts +245 -245
- package/src/node/logger-cli-contribution.ts +168 -168
- package/src/node/main.ts +33 -33
- package/src/node/messaging/binary-message-pipe.ts +168 -168
- package/src/node/messaging/connection-container-module.ts +96 -96
- package/src/node/messaging/default-messaging-service.ts +129 -129
- package/src/node/messaging/frontend-connection-service.ts +24 -24
- package/src/node/messaging/index.ts +19 -19
- package/src/node/messaging/ipc-bootstrap.ts +27 -27
- package/src/node/messaging/ipc-channel.ts +77 -77
- package/src/node/messaging/ipc-connection-provider.ts +107 -107
- package/src/node/messaging/ipc-protocol.ts +76 -76
- package/src/node/messaging/messaging-backend-module.ts +52 -52
- package/src/node/messaging/messaging-listeners.ts +52 -52
- package/src/node/messaging/messaging-service.ts +46 -46
- package/src/node/messaging/test/test-web-socket-channel.ts +61 -61
- package/src/node/messaging/websocket-endpoint.ts +79 -79
- package/src/node/messaging/websocket-frontend-connection-service.ts +186 -186
- package/src/node/os-backend-provider.ts +25 -25
- package/src/node/performance/index.ts +18 -18
- package/src/node/performance/measurement-backend-bindings.ts +35 -35
- package/src/node/performance/node-stopwatch.ts +40 -40
- package/src/node/process-utils.spec.ts +48 -48
- package/src/node/process-utils.ts +102 -102
- package/src/node/remote/backend-remote-service.ts +25 -25
- package/src/node/remote/remote-cli-contribution.ts +34 -34
- package/src/node/remote/remote-copy-contribution.ts +45 -45
- package/src/node/request/backend-request-facade.ts +39 -39
- package/src/node/request/backend-request-module.ts +25 -25
- package/src/node/request/proxy-cli-contribution.ts +65 -65
- package/src/node/ws-request-validators.ts +56 -56
- package/src/typings/native-keymap.d.ts +108 -108
|
@@ -1,467 +1,467 @@
|
|
|
1
|
-
// *****************************************************************************
|
|
2
|
-
// Copyright (C) 2020 Red Hat, Inc. and others.
|
|
3
|
-
//
|
|
4
|
-
// This program and the accompanying materials are made available under the
|
|
5
|
-
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
-
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
-
//
|
|
8
|
-
// This Source Code may also be made available under the following Secondary
|
|
9
|
-
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
-
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
-
// with the GNU Classpath Exception which is available at
|
|
12
|
-
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
-
//
|
|
14
|
-
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
-
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
/*---------------------------------------------------------------------------------------------
|
|
18
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
19
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
20
|
-
*--------------------------------------------------------------------------------------------*/
|
|
21
|
-
// code copied and modified from https://github.com/microsoft/vscode/blob/1.47.3/src/vs/workbench/services/authentication/browser/authenticationService.ts
|
|
22
|
-
|
|
23
|
-
import { injectable, inject, postConstruct } from 'inversify';
|
|
24
|
-
import { Emitter, Event } from '../common/event';
|
|
25
|
-
import { StorageService } from '../browser/storage-service';
|
|
26
|
-
import { Disposable, DisposableCollection } from '../common/disposable';
|
|
27
|
-
import { ACCOUNTS_MENU, ACCOUNTS_SUBMENU, MenuModelRegistry } from '../common/menu';
|
|
28
|
-
import { Command, CommandRegistry } from '../common/command';
|
|
29
|
-
import { nls } from '../common/nls';
|
|
30
|
-
|
|
31
|
-
export interface AuthenticationSessionAccountInformation {
|
|
32
|
-
readonly id: string;
|
|
33
|
-
readonly label: string;
|
|
34
|
-
}
|
|
35
|
-
export interface AuthenticationProviderSessionOptions {
|
|
36
|
-
/**
|
|
37
|
-
* The account that is being asked about. If this is passed in, the provider should
|
|
38
|
-
* attempt to return the sessions that are only related to this account.
|
|
39
|
-
*/
|
|
40
|
-
account?: AuthenticationSessionAccountInformation;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface AuthenticationSession {
|
|
44
|
-
id: string;
|
|
45
|
-
accessToken: string;
|
|
46
|
-
account: AuthenticationSessionAccountInformation;
|
|
47
|
-
scopes: ReadonlyArray<string>;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface AuthenticationProviderInformation {
|
|
51
|
-
id: string;
|
|
52
|
-
label: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** Should match the definition from the theia/vscode types */
|
|
56
|
-
export interface AuthenticationProviderAuthenticationSessionsChangeEvent {
|
|
57
|
-
readonly added: readonly AuthenticationSession[] | undefined;
|
|
58
|
-
readonly removed: readonly AuthenticationSession[] | undefined;
|
|
59
|
-
readonly changed: readonly AuthenticationSession[] | undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface SessionRequest {
|
|
63
|
-
disposables: Disposable[];
|
|
64
|
-
requestingExtensionIds: string[];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface SessionRequestInfo {
|
|
68
|
-
[scopes: string]: SessionRequest;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Our authentication provider should at least contain the following information:
|
|
73
|
-
* - The signature of authentication providers from vscode
|
|
74
|
-
* - Registration information about the provider (id, label)
|
|
75
|
-
* - Provider options (supportsMultipleAccounts)
|
|
76
|
-
*
|
|
77
|
-
* Additionally, we provide the possibility to sign out of a specific account name.
|
|
78
|
-
*/
|
|
79
|
-
export interface AuthenticationProvider {
|
|
80
|
-
id: string;
|
|
81
|
-
|
|
82
|
-
label: string;
|
|
83
|
-
|
|
84
|
-
supportsMultipleAccounts: boolean;
|
|
85
|
-
|
|
86
|
-
hasSessions(): boolean;
|
|
87
|
-
|
|
88
|
-
signOut(accountName: string): Promise<void>;
|
|
89
|
-
|
|
90
|
-
updateSessionItems(event: AuthenticationProviderAuthenticationSessionsChangeEvent): Promise<void>;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* An [event](#Event) which fires when the array of sessions has changed, or data
|
|
94
|
-
* within a session has changed.
|
|
95
|
-
*/
|
|
96
|
-
readonly onDidChangeSessions: Event<AuthenticationProviderAuthenticationSessionsChangeEvent>;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Get a list of sessions.
|
|
100
|
-
* @param scopes An optional list of scopes. If provided, the sessions returned should match
|
|
101
|
-
* these permissions, otherwise all sessions should be returned.
|
|
102
|
-
* @param account The optional account that you would like to get the session for
|
|
103
|
-
* @returns A promise that resolves to an array of authentication sessions.
|
|
104
|
-
*/
|
|
105
|
-
getSessions(scopes: string[] | undefined, account?: AuthenticationSessionAccountInformation): Thenable<ReadonlyArray<AuthenticationSession>>;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Prompts a user to login.
|
|
109
|
-
* @param scopes A list of scopes, permissions, that the new session should be created with.
|
|
110
|
-
* @param options The options for createing the session
|
|
111
|
-
* @returns A promise that resolves to an authentication session.
|
|
112
|
-
*/
|
|
113
|
-
createSession(scopes: string[], options: AuthenticationProviderSessionOptions): Thenable<AuthenticationSession>;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Removes the session corresponding to session id.
|
|
117
|
-
* @param sessionId The id of the session to remove.
|
|
118
|
-
*/
|
|
119
|
-
removeSession(sessionId: string): Thenable<void>;
|
|
120
|
-
}
|
|
121
|
-
export const AuthenticationService = Symbol('AuthenticationService');
|
|
122
|
-
|
|
123
|
-
export interface AuthenticationService {
|
|
124
|
-
isAuthenticationProviderRegistered(id: string): boolean;
|
|
125
|
-
getProviderIds(): string[];
|
|
126
|
-
registerAuthenticationProvider(id: string, provider: AuthenticationProvider): void;
|
|
127
|
-
unregisterAuthenticationProvider(id: string): void;
|
|
128
|
-
requestNewSession(id: string, scopes: string[], extensionId: string, extensionName: string): void;
|
|
129
|
-
updateSessions(providerId: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent): void;
|
|
130
|
-
|
|
131
|
-
readonly onDidRegisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
|
|
132
|
-
readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
|
|
133
|
-
|
|
134
|
-
readonly onDidChangeSessions: Event<{ providerId: string, label: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent }>;
|
|
135
|
-
readonly onDidUpdateSignInCount: Event<number>;
|
|
136
|
-
getSessions(providerId: string, scopes?: string[], user?: AuthenticationSessionAccountInformation): Promise<ReadonlyArray<AuthenticationSession>>;
|
|
137
|
-
getLabel(providerId: string): string;
|
|
138
|
-
supportsMultipleAccounts(providerId: string): boolean;
|
|
139
|
-
login(providerId: string, scopes: string[], options?: AuthenticationProviderSessionOptions): Promise<AuthenticationSession>;
|
|
140
|
-
logout(providerId: string, sessionId: string): Promise<void>;
|
|
141
|
-
|
|
142
|
-
signOutOfAccount(providerId: string, accountName: string): Promise<void>;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface SessionChangeEvent {
|
|
146
|
-
providerId: string,
|
|
147
|
-
label: string,
|
|
148
|
-
event: AuthenticationProviderAuthenticationSessionsChangeEvent
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
@injectable()
|
|
152
|
-
export class AuthenticationServiceImpl implements AuthenticationService {
|
|
153
|
-
private noAccountsMenuItem: Disposable | undefined;
|
|
154
|
-
private noAccountsCommand: Command = { id: 'noAccounts' };
|
|
155
|
-
private signInRequestItems = new Map<string, SessionRequestInfo>();
|
|
156
|
-
private sessionMap = new Map<string, DisposableCollection>();
|
|
157
|
-
|
|
158
|
-
protected authenticationProviders: Map<string, AuthenticationProvider> = new Map<string, AuthenticationProvider>();
|
|
159
|
-
|
|
160
|
-
private readonly onDidRegisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
161
|
-
readonly onDidRegisterAuthenticationProvider: Event<AuthenticationProviderInformation> = this.onDidRegisterAuthenticationProviderEmitter.event;
|
|
162
|
-
|
|
163
|
-
private readonly onDidUnregisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
164
|
-
readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation> = this.onDidUnregisterAuthenticationProviderEmitter.event;
|
|
165
|
-
|
|
166
|
-
private readonly onDidChangeSessionsEmitter: Emitter<SessionChangeEvent> = new Emitter<SessionChangeEvent>();
|
|
167
|
-
readonly onDidChangeSessions: Event<SessionChangeEvent> = this.onDidChangeSessionsEmitter.event;
|
|
168
|
-
|
|
169
|
-
private readonly onDidChangeSignInCountEmitter: Emitter<number> = new Emitter<number>();
|
|
170
|
-
readonly onDidUpdateSignInCount: Event<number> = this.onDidChangeSignInCountEmitter.event;
|
|
171
|
-
|
|
172
|
-
@inject(MenuModelRegistry) protected readonly menus: MenuModelRegistry;
|
|
173
|
-
@inject(CommandRegistry) protected readonly commands: CommandRegistry;
|
|
174
|
-
@inject(StorageService) protected readonly storageService: StorageService;
|
|
175
|
-
|
|
176
|
-
@postConstruct()
|
|
177
|
-
init(): void {
|
|
178
|
-
this.onDidChangeSessions(event => this.handleSessionChange(event));
|
|
179
|
-
this.commands.registerCommand(this.noAccountsCommand, {
|
|
180
|
-
execute: () => { },
|
|
181
|
-
isEnabled: () => false
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
protected async handleSessionChange(changeEvent: SessionChangeEvent): Promise<void> {
|
|
186
|
-
if (changeEvent.event.added && changeEvent.event.added.length > 0) {
|
|
187
|
-
const sessions = await this.getSessions(changeEvent.providerId);
|
|
188
|
-
sessions.forEach(session => {
|
|
189
|
-
if (!this.sessionMap.get(session.id)) {
|
|
190
|
-
this.sessionMap.set(session.id, this.createAccountUi(changeEvent.providerId, changeEvent.label, session));
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
for (const removed of changeEvent.event.removed || []) {
|
|
195
|
-
const sessionId = typeof removed === 'string' ? removed : removed?.id;
|
|
196
|
-
if (sessionId) {
|
|
197
|
-
this.sessionMap.get(sessionId)?.dispose();
|
|
198
|
-
this.sessionMap.delete(sessionId);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
protected createAccountUi(providerId: string, providerLabel: string, session: AuthenticationSession): DisposableCollection {
|
|
204
|
-
// unregister old commands and menus if present (there is only one per account but there may be several sessions per account)
|
|
205
|
-
const providerAccountId = `account-sign-out-${providerId}-${session.account.id}`;
|
|
206
|
-
this.commands.unregisterCommand(providerAccountId);
|
|
207
|
-
|
|
208
|
-
const providerAccountSubmenu = [...ACCOUNTS_SUBMENU, providerAccountId];
|
|
209
|
-
this.menus.unregisterMenuAction({ commandId: providerAccountId }, providerAccountSubmenu);
|
|
210
|
-
|
|
211
|
-
// register new command and menu entry for the sessions account
|
|
212
|
-
const disposables = new DisposableCollection();
|
|
213
|
-
disposables.push(this.commands.registerCommand({ id: providerAccountId }, {
|
|
214
|
-
execute: async () => {
|
|
215
|
-
this.signOutOfAccount(providerId, session.account.label);
|
|
216
|
-
}
|
|
217
|
-
}));
|
|
218
|
-
this.menus.registerSubmenu(providerAccountSubmenu, `${session.account.label} (${providerLabel})`);
|
|
219
|
-
disposables.push(this.menus.registerMenuAction(providerAccountSubmenu, {
|
|
220
|
-
label: nls.localizeByDefault('Sign Out'),
|
|
221
|
-
commandId: providerAccountId
|
|
222
|
-
}));
|
|
223
|
-
return disposables;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
getProviderIds(): string[] {
|
|
227
|
-
const providerIds: string[] = [];
|
|
228
|
-
this.authenticationProviders.forEach(provider => {
|
|
229
|
-
providerIds.push(provider.id);
|
|
230
|
-
});
|
|
231
|
-
return providerIds;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
isAuthenticationProviderRegistered(id: string): boolean {
|
|
235
|
-
return this.authenticationProviders.has(id);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
private updateAccountsMenuItem(): void {
|
|
239
|
-
let hasSession = false;
|
|
240
|
-
this.authenticationProviders.forEach(async provider => {
|
|
241
|
-
hasSession = hasSession || provider.hasSessions();
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
if (hasSession && this.noAccountsMenuItem) {
|
|
245
|
-
this.noAccountsMenuItem.dispose();
|
|
246
|
-
this.noAccountsMenuItem = undefined;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (!hasSession && !this.noAccountsMenuItem) {
|
|
250
|
-
this.noAccountsMenuItem = this.menus.registerMenuAction(ACCOUNTS_MENU, {
|
|
251
|
-
label: 'You are not signed in to any accounts',
|
|
252
|
-
order: '0',
|
|
253
|
-
commandId: this.noAccountsCommand.id
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
registerAuthenticationProvider(id: string, authenticationProvider: AuthenticationProvider): void {
|
|
259
|
-
if (this.authenticationProviders.get(id)) {
|
|
260
|
-
throw new Error(`An authentication provider with id '${id}' is already registered.`);
|
|
261
|
-
}
|
|
262
|
-
this.authenticationProviders.set(id, authenticationProvider);
|
|
263
|
-
this.onDidRegisterAuthenticationProviderEmitter.fire({ id, label: authenticationProvider.label });
|
|
264
|
-
|
|
265
|
-
this.updateAccountsMenuItem();
|
|
266
|
-
console.log(`An authentication provider with id '${id}' was registered.`);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
unregisterAuthenticationProvider(id: string): void {
|
|
270
|
-
const provider = this.authenticationProviders.get(id);
|
|
271
|
-
if (provider) {
|
|
272
|
-
this.authenticationProviders.delete(id);
|
|
273
|
-
this.onDidUnregisterAuthenticationProviderEmitter.fire({ id, label: provider.label });
|
|
274
|
-
this.updateAccountsMenuItem();
|
|
275
|
-
} else {
|
|
276
|
-
console.error(`Failed to unregister an authentication provider. A provider with id '${id}' was not found.`);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
async updateSessions(id: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent): Promise<void> {
|
|
281
|
-
const provider = this.authenticationProviders.get(id);
|
|
282
|
-
if (provider) {
|
|
283
|
-
await provider.updateSessionItems(event);
|
|
284
|
-
this.onDidChangeSessionsEmitter.fire({ providerId: id, label: provider.label, event: event });
|
|
285
|
-
this.updateAccountsMenuItem();
|
|
286
|
-
|
|
287
|
-
if (event.added) {
|
|
288
|
-
await this.updateNewSessionRequests(provider);
|
|
289
|
-
}
|
|
290
|
-
} else {
|
|
291
|
-
console.error(`Failed to update an authentication session. An authentication provider with id '${id}' was not found.`);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
private async updateNewSessionRequests(provider: AuthenticationProvider): Promise<void> {
|
|
296
|
-
const existingRequestsForProvider = this.signInRequestItems.get(provider.id);
|
|
297
|
-
if (!existingRequestsForProvider) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const previousSize = this.signInRequestItems.size;
|
|
302
|
-
const sessions = await provider.getSessions(undefined);
|
|
303
|
-
Object.keys(existingRequestsForProvider).forEach(requestedScopes => {
|
|
304
|
-
if (sessions.some(session => session.scopes.slice().sort().join('') === requestedScopes)) {
|
|
305
|
-
const sessionRequest = existingRequestsForProvider[requestedScopes];
|
|
306
|
-
if (sessionRequest) {
|
|
307
|
-
sessionRequest.disposables.forEach(item => item.dispose());
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
delete existingRequestsForProvider[requestedScopes];
|
|
311
|
-
if (Object.keys(existingRequestsForProvider).length === 0) {
|
|
312
|
-
this.signInRequestItems.delete(provider.id);
|
|
313
|
-
} else {
|
|
314
|
-
this.signInRequestItems.set(provider.id, existingRequestsForProvider);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
if (previousSize !== this.signInRequestItems.size) {
|
|
319
|
-
this.onDidChangeSignInCountEmitter.fire(this.signInRequestItems.size);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
async requestNewSession(providerId: string, scopes: string[], extensionId: string, extensionName: string): Promise<void> {
|
|
324
|
-
let provider = this.authenticationProviders.get(providerId);
|
|
325
|
-
if (!provider) {
|
|
326
|
-
// Activate has already been called for the authentication provider, but it cannot block on registering itself
|
|
327
|
-
// since this is sync and returns a disposable. So, wait for registration event to fire that indicates the
|
|
328
|
-
// provider is now in the map.
|
|
329
|
-
await new Promise<void>((resolve, _) => {
|
|
330
|
-
this.onDidRegisterAuthenticationProvider(e => {
|
|
331
|
-
if (e.id === providerId) {
|
|
332
|
-
provider = this.authenticationProviders.get(providerId);
|
|
333
|
-
resolve(undefined);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (provider) {
|
|
340
|
-
const providerRequests = this.signInRequestItems.get(providerId);
|
|
341
|
-
const scopesList = scopes.sort().join('');
|
|
342
|
-
const extensionHasExistingRequest = providerRequests
|
|
343
|
-
&& providerRequests[scopesList]
|
|
344
|
-
&& providerRequests[scopesList].requestingExtensionIds.indexOf(extensionId) > -1;
|
|
345
|
-
|
|
346
|
-
if (extensionHasExistingRequest) {
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const menuItem = this.menus.registerMenuAction(ACCOUNTS_SUBMENU, {
|
|
351
|
-
label: nls.localizeByDefault('Sign in with {0} to use {1} (1)', provider.label, extensionName),
|
|
352
|
-
order: '1',
|
|
353
|
-
commandId: `${extensionId}signIn`,
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
const signInCommand = this.commands.registerCommand({ id: `${extensionId}signIn` }, {
|
|
357
|
-
execute: async () => {
|
|
358
|
-
const session = await this.login(providerId, scopes);
|
|
359
|
-
|
|
360
|
-
// Add extension to allow list since user explicitly signed in on behalf of it
|
|
361
|
-
const allowList = await readAllowedExtensions(this.storageService, providerId, session.account.label);
|
|
362
|
-
if (!allowList.find(allowed => allowed.id === extensionId)) {
|
|
363
|
-
allowList.push({ id: extensionId, name: extensionName });
|
|
364
|
-
this.storageService.setData(`authentication-trusted-extensions-${providerId}-${session.account.label}`, JSON.stringify(allowList));
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// And also set it as the preferred account for the extension
|
|
368
|
-
this.storageService.setData(`authentication-session-${extensionName}-${providerId}`, session.id);
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
const previousSize = this.signInRequestItems.size;
|
|
373
|
-
if (providerRequests) {
|
|
374
|
-
const existingRequest = providerRequests[scopesList] || { disposables: [], requestingExtensionIds: [] };
|
|
375
|
-
|
|
376
|
-
providerRequests[scopesList] = {
|
|
377
|
-
disposables: [...existingRequest.disposables, menuItem, signInCommand],
|
|
378
|
-
requestingExtensionIds: [...existingRequest.requestingExtensionIds, extensionId]
|
|
379
|
-
};
|
|
380
|
-
this.signInRequestItems.set(providerId, providerRequests);
|
|
381
|
-
} else {
|
|
382
|
-
this.signInRequestItems.set(providerId, {
|
|
383
|
-
[scopesList]: {
|
|
384
|
-
disposables: [menuItem, signInCommand],
|
|
385
|
-
requestingExtensionIds: [extensionId]
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
if (previousSize !== this.signInRequestItems.size) {
|
|
390
|
-
this.onDidChangeSignInCountEmitter.fire(this.signInRequestItems.size);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
getLabel(id: string): string {
|
|
396
|
-
const authProvider = this.authenticationProviders.get(id);
|
|
397
|
-
if (authProvider) {
|
|
398
|
-
return authProvider.label;
|
|
399
|
-
} else {
|
|
400
|
-
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
supportsMultipleAccounts(id: string): boolean {
|
|
405
|
-
const authProvider = this.authenticationProviders.get(id);
|
|
406
|
-
if (authProvider) {
|
|
407
|
-
return authProvider.supportsMultipleAccounts;
|
|
408
|
-
} else {
|
|
409
|
-
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
async getSessions(id: string, scopes?: string[], user?: AuthenticationSessionAccountInformation): Promise<ReadonlyArray<AuthenticationSession>> {
|
|
414
|
-
const authProvider = this.authenticationProviders.get(id);
|
|
415
|
-
if (authProvider) {
|
|
416
|
-
return authProvider.getSessions(scopes, user);
|
|
417
|
-
} else {
|
|
418
|
-
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
async login(id: string, scopes: string[], options?: AuthenticationProviderSessionOptions): Promise<AuthenticationSession> {
|
|
423
|
-
const authProvider = this.authenticationProviders.get(id);
|
|
424
|
-
if (authProvider) {
|
|
425
|
-
return authProvider.createSession(scopes, options || {});
|
|
426
|
-
} else {
|
|
427
|
-
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
async logout(id: string, sessionId: string): Promise<void> {
|
|
432
|
-
const authProvider = this.authenticationProviders.get(id);
|
|
433
|
-
if (authProvider) {
|
|
434
|
-
return authProvider.removeSession(sessionId);
|
|
435
|
-
} else {
|
|
436
|
-
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
async signOutOfAccount(id: string, accountName: string): Promise<void> {
|
|
441
|
-
const authProvider = this.authenticationProviders.get(id);
|
|
442
|
-
if (authProvider) {
|
|
443
|
-
return authProvider.signOut(accountName);
|
|
444
|
-
} else {
|
|
445
|
-
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
export interface AllowedExtension {
|
|
451
|
-
id: string;
|
|
452
|
-
name: string;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
export async function readAllowedExtensions(storageService: StorageService, providerId: string, accountName: string): Promise<AllowedExtension[]> {
|
|
456
|
-
let trustedExtensions: AllowedExtension[] = [];
|
|
457
|
-
try {
|
|
458
|
-
const trustedExtensionSrc: string | undefined = await storageService.getData(`authentication-trusted-extensions-${providerId}-${accountName}`);
|
|
459
|
-
if (trustedExtensionSrc) {
|
|
460
|
-
trustedExtensions = JSON.parse(trustedExtensionSrc);
|
|
461
|
-
}
|
|
462
|
-
} catch (err) {
|
|
463
|
-
console.error(err);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
return trustedExtensions;
|
|
467
|
-
}
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2020 Red Hat, Inc. and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
/*---------------------------------------------------------------------------------------------
|
|
18
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
19
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
20
|
+
*--------------------------------------------------------------------------------------------*/
|
|
21
|
+
// code copied and modified from https://github.com/microsoft/vscode/blob/1.47.3/src/vs/workbench/services/authentication/browser/authenticationService.ts
|
|
22
|
+
|
|
23
|
+
import { injectable, inject, postConstruct } from 'inversify';
|
|
24
|
+
import { Emitter, Event } from '../common/event';
|
|
25
|
+
import { StorageService } from '../browser/storage-service';
|
|
26
|
+
import { Disposable, DisposableCollection } from '../common/disposable';
|
|
27
|
+
import { ACCOUNTS_MENU, ACCOUNTS_SUBMENU, MenuModelRegistry } from '../common/menu';
|
|
28
|
+
import { Command, CommandRegistry } from '../common/command';
|
|
29
|
+
import { nls } from '../common/nls';
|
|
30
|
+
|
|
31
|
+
export interface AuthenticationSessionAccountInformation {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly label: string;
|
|
34
|
+
}
|
|
35
|
+
export interface AuthenticationProviderSessionOptions {
|
|
36
|
+
/**
|
|
37
|
+
* The account that is being asked about. If this is passed in, the provider should
|
|
38
|
+
* attempt to return the sessions that are only related to this account.
|
|
39
|
+
*/
|
|
40
|
+
account?: AuthenticationSessionAccountInformation;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface AuthenticationSession {
|
|
44
|
+
id: string;
|
|
45
|
+
accessToken: string;
|
|
46
|
+
account: AuthenticationSessionAccountInformation;
|
|
47
|
+
scopes: ReadonlyArray<string>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface AuthenticationProviderInformation {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Should match the definition from the theia/vscode types */
|
|
56
|
+
export interface AuthenticationProviderAuthenticationSessionsChangeEvent {
|
|
57
|
+
readonly added: readonly AuthenticationSession[] | undefined;
|
|
58
|
+
readonly removed: readonly AuthenticationSession[] | undefined;
|
|
59
|
+
readonly changed: readonly AuthenticationSession[] | undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface SessionRequest {
|
|
63
|
+
disposables: Disposable[];
|
|
64
|
+
requestingExtensionIds: string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface SessionRequestInfo {
|
|
68
|
+
[scopes: string]: SessionRequest;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Our authentication provider should at least contain the following information:
|
|
73
|
+
* - The signature of authentication providers from vscode
|
|
74
|
+
* - Registration information about the provider (id, label)
|
|
75
|
+
* - Provider options (supportsMultipleAccounts)
|
|
76
|
+
*
|
|
77
|
+
* Additionally, we provide the possibility to sign out of a specific account name.
|
|
78
|
+
*/
|
|
79
|
+
export interface AuthenticationProvider {
|
|
80
|
+
id: string;
|
|
81
|
+
|
|
82
|
+
label: string;
|
|
83
|
+
|
|
84
|
+
supportsMultipleAccounts: boolean;
|
|
85
|
+
|
|
86
|
+
hasSessions(): boolean;
|
|
87
|
+
|
|
88
|
+
signOut(accountName: string): Promise<void>;
|
|
89
|
+
|
|
90
|
+
updateSessionItems(event: AuthenticationProviderAuthenticationSessionsChangeEvent): Promise<void>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* An [event](#Event) which fires when the array of sessions has changed, or data
|
|
94
|
+
* within a session has changed.
|
|
95
|
+
*/
|
|
96
|
+
readonly onDidChangeSessions: Event<AuthenticationProviderAuthenticationSessionsChangeEvent>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get a list of sessions.
|
|
100
|
+
* @param scopes An optional list of scopes. If provided, the sessions returned should match
|
|
101
|
+
* these permissions, otherwise all sessions should be returned.
|
|
102
|
+
* @param account The optional account that you would like to get the session for
|
|
103
|
+
* @returns A promise that resolves to an array of authentication sessions.
|
|
104
|
+
*/
|
|
105
|
+
getSessions(scopes: string[] | undefined, account?: AuthenticationSessionAccountInformation): Thenable<ReadonlyArray<AuthenticationSession>>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Prompts a user to login.
|
|
109
|
+
* @param scopes A list of scopes, permissions, that the new session should be created with.
|
|
110
|
+
* @param options The options for createing the session
|
|
111
|
+
* @returns A promise that resolves to an authentication session.
|
|
112
|
+
*/
|
|
113
|
+
createSession(scopes: string[], options: AuthenticationProviderSessionOptions): Thenable<AuthenticationSession>;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Removes the session corresponding to session id.
|
|
117
|
+
* @param sessionId The id of the session to remove.
|
|
118
|
+
*/
|
|
119
|
+
removeSession(sessionId: string): Thenable<void>;
|
|
120
|
+
}
|
|
121
|
+
export const AuthenticationService = Symbol('AuthenticationService');
|
|
122
|
+
|
|
123
|
+
export interface AuthenticationService {
|
|
124
|
+
isAuthenticationProviderRegistered(id: string): boolean;
|
|
125
|
+
getProviderIds(): string[];
|
|
126
|
+
registerAuthenticationProvider(id: string, provider: AuthenticationProvider): void;
|
|
127
|
+
unregisterAuthenticationProvider(id: string): void;
|
|
128
|
+
requestNewSession(id: string, scopes: string[], extensionId: string, extensionName: string): void;
|
|
129
|
+
updateSessions(providerId: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent): void;
|
|
130
|
+
|
|
131
|
+
readonly onDidRegisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
|
|
132
|
+
readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
|
|
133
|
+
|
|
134
|
+
readonly onDidChangeSessions: Event<{ providerId: string, label: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent }>;
|
|
135
|
+
readonly onDidUpdateSignInCount: Event<number>;
|
|
136
|
+
getSessions(providerId: string, scopes?: string[], user?: AuthenticationSessionAccountInformation): Promise<ReadonlyArray<AuthenticationSession>>;
|
|
137
|
+
getLabel(providerId: string): string;
|
|
138
|
+
supportsMultipleAccounts(providerId: string): boolean;
|
|
139
|
+
login(providerId: string, scopes: string[], options?: AuthenticationProviderSessionOptions): Promise<AuthenticationSession>;
|
|
140
|
+
logout(providerId: string, sessionId: string): Promise<void>;
|
|
141
|
+
|
|
142
|
+
signOutOfAccount(providerId: string, accountName: string): Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface SessionChangeEvent {
|
|
146
|
+
providerId: string,
|
|
147
|
+
label: string,
|
|
148
|
+
event: AuthenticationProviderAuthenticationSessionsChangeEvent
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@injectable()
|
|
152
|
+
export class AuthenticationServiceImpl implements AuthenticationService {
|
|
153
|
+
private noAccountsMenuItem: Disposable | undefined;
|
|
154
|
+
private noAccountsCommand: Command = { id: 'noAccounts' };
|
|
155
|
+
private signInRequestItems = new Map<string, SessionRequestInfo>();
|
|
156
|
+
private sessionMap = new Map<string, DisposableCollection>();
|
|
157
|
+
|
|
158
|
+
protected authenticationProviders: Map<string, AuthenticationProvider> = new Map<string, AuthenticationProvider>();
|
|
159
|
+
|
|
160
|
+
private readonly onDidRegisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
161
|
+
readonly onDidRegisterAuthenticationProvider: Event<AuthenticationProviderInformation> = this.onDidRegisterAuthenticationProviderEmitter.event;
|
|
162
|
+
|
|
163
|
+
private readonly onDidUnregisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
164
|
+
readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation> = this.onDidUnregisterAuthenticationProviderEmitter.event;
|
|
165
|
+
|
|
166
|
+
private readonly onDidChangeSessionsEmitter: Emitter<SessionChangeEvent> = new Emitter<SessionChangeEvent>();
|
|
167
|
+
readonly onDidChangeSessions: Event<SessionChangeEvent> = this.onDidChangeSessionsEmitter.event;
|
|
168
|
+
|
|
169
|
+
private readonly onDidChangeSignInCountEmitter: Emitter<number> = new Emitter<number>();
|
|
170
|
+
readonly onDidUpdateSignInCount: Event<number> = this.onDidChangeSignInCountEmitter.event;
|
|
171
|
+
|
|
172
|
+
@inject(MenuModelRegistry) protected readonly menus: MenuModelRegistry;
|
|
173
|
+
@inject(CommandRegistry) protected readonly commands: CommandRegistry;
|
|
174
|
+
@inject(StorageService) protected readonly storageService: StorageService;
|
|
175
|
+
|
|
176
|
+
@postConstruct()
|
|
177
|
+
init(): void {
|
|
178
|
+
this.onDidChangeSessions(event => this.handleSessionChange(event));
|
|
179
|
+
this.commands.registerCommand(this.noAccountsCommand, {
|
|
180
|
+
execute: () => { },
|
|
181
|
+
isEnabled: () => false
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
protected async handleSessionChange(changeEvent: SessionChangeEvent): Promise<void> {
|
|
186
|
+
if (changeEvent.event.added && changeEvent.event.added.length > 0) {
|
|
187
|
+
const sessions = await this.getSessions(changeEvent.providerId);
|
|
188
|
+
sessions.forEach(session => {
|
|
189
|
+
if (!this.sessionMap.get(session.id)) {
|
|
190
|
+
this.sessionMap.set(session.id, this.createAccountUi(changeEvent.providerId, changeEvent.label, session));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
for (const removed of changeEvent.event.removed || []) {
|
|
195
|
+
const sessionId = typeof removed === 'string' ? removed : removed?.id;
|
|
196
|
+
if (sessionId) {
|
|
197
|
+
this.sessionMap.get(sessionId)?.dispose();
|
|
198
|
+
this.sessionMap.delete(sessionId);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
protected createAccountUi(providerId: string, providerLabel: string, session: AuthenticationSession): DisposableCollection {
|
|
204
|
+
// unregister old commands and menus if present (there is only one per account but there may be several sessions per account)
|
|
205
|
+
const providerAccountId = `account-sign-out-${providerId}-${session.account.id}`;
|
|
206
|
+
this.commands.unregisterCommand(providerAccountId);
|
|
207
|
+
|
|
208
|
+
const providerAccountSubmenu = [...ACCOUNTS_SUBMENU, providerAccountId];
|
|
209
|
+
this.menus.unregisterMenuAction({ commandId: providerAccountId }, providerAccountSubmenu);
|
|
210
|
+
|
|
211
|
+
// register new command and menu entry for the sessions account
|
|
212
|
+
const disposables = new DisposableCollection();
|
|
213
|
+
disposables.push(this.commands.registerCommand({ id: providerAccountId }, {
|
|
214
|
+
execute: async () => {
|
|
215
|
+
this.signOutOfAccount(providerId, session.account.label);
|
|
216
|
+
}
|
|
217
|
+
}));
|
|
218
|
+
this.menus.registerSubmenu(providerAccountSubmenu, `${session.account.label} (${providerLabel})`);
|
|
219
|
+
disposables.push(this.menus.registerMenuAction(providerAccountSubmenu, {
|
|
220
|
+
label: nls.localizeByDefault('Sign Out'),
|
|
221
|
+
commandId: providerAccountId
|
|
222
|
+
}));
|
|
223
|
+
return disposables;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
getProviderIds(): string[] {
|
|
227
|
+
const providerIds: string[] = [];
|
|
228
|
+
this.authenticationProviders.forEach(provider => {
|
|
229
|
+
providerIds.push(provider.id);
|
|
230
|
+
});
|
|
231
|
+
return providerIds;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
isAuthenticationProviderRegistered(id: string): boolean {
|
|
235
|
+
return this.authenticationProviders.has(id);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private updateAccountsMenuItem(): void {
|
|
239
|
+
let hasSession = false;
|
|
240
|
+
this.authenticationProviders.forEach(async provider => {
|
|
241
|
+
hasSession = hasSession || provider.hasSessions();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (hasSession && this.noAccountsMenuItem) {
|
|
245
|
+
this.noAccountsMenuItem.dispose();
|
|
246
|
+
this.noAccountsMenuItem = undefined;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!hasSession && !this.noAccountsMenuItem) {
|
|
250
|
+
this.noAccountsMenuItem = this.menus.registerMenuAction(ACCOUNTS_MENU, {
|
|
251
|
+
label: 'You are not signed in to any accounts',
|
|
252
|
+
order: '0',
|
|
253
|
+
commandId: this.noAccountsCommand.id
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
registerAuthenticationProvider(id: string, authenticationProvider: AuthenticationProvider): void {
|
|
259
|
+
if (this.authenticationProviders.get(id)) {
|
|
260
|
+
throw new Error(`An authentication provider with id '${id}' is already registered.`);
|
|
261
|
+
}
|
|
262
|
+
this.authenticationProviders.set(id, authenticationProvider);
|
|
263
|
+
this.onDidRegisterAuthenticationProviderEmitter.fire({ id, label: authenticationProvider.label });
|
|
264
|
+
|
|
265
|
+
this.updateAccountsMenuItem();
|
|
266
|
+
console.log(`An authentication provider with id '${id}' was registered.`);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
unregisterAuthenticationProvider(id: string): void {
|
|
270
|
+
const provider = this.authenticationProviders.get(id);
|
|
271
|
+
if (provider) {
|
|
272
|
+
this.authenticationProviders.delete(id);
|
|
273
|
+
this.onDidUnregisterAuthenticationProviderEmitter.fire({ id, label: provider.label });
|
|
274
|
+
this.updateAccountsMenuItem();
|
|
275
|
+
} else {
|
|
276
|
+
console.error(`Failed to unregister an authentication provider. A provider with id '${id}' was not found.`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async updateSessions(id: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent): Promise<void> {
|
|
281
|
+
const provider = this.authenticationProviders.get(id);
|
|
282
|
+
if (provider) {
|
|
283
|
+
await provider.updateSessionItems(event);
|
|
284
|
+
this.onDidChangeSessionsEmitter.fire({ providerId: id, label: provider.label, event: event });
|
|
285
|
+
this.updateAccountsMenuItem();
|
|
286
|
+
|
|
287
|
+
if (event.added) {
|
|
288
|
+
await this.updateNewSessionRequests(provider);
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
console.error(`Failed to update an authentication session. An authentication provider with id '${id}' was not found.`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private async updateNewSessionRequests(provider: AuthenticationProvider): Promise<void> {
|
|
296
|
+
const existingRequestsForProvider = this.signInRequestItems.get(provider.id);
|
|
297
|
+
if (!existingRequestsForProvider) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const previousSize = this.signInRequestItems.size;
|
|
302
|
+
const sessions = await provider.getSessions(undefined);
|
|
303
|
+
Object.keys(existingRequestsForProvider).forEach(requestedScopes => {
|
|
304
|
+
if (sessions.some(session => session.scopes.slice().sort().join('') === requestedScopes)) {
|
|
305
|
+
const sessionRequest = existingRequestsForProvider[requestedScopes];
|
|
306
|
+
if (sessionRequest) {
|
|
307
|
+
sessionRequest.disposables.forEach(item => item.dispose());
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
delete existingRequestsForProvider[requestedScopes];
|
|
311
|
+
if (Object.keys(existingRequestsForProvider).length === 0) {
|
|
312
|
+
this.signInRequestItems.delete(provider.id);
|
|
313
|
+
} else {
|
|
314
|
+
this.signInRequestItems.set(provider.id, existingRequestsForProvider);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
if (previousSize !== this.signInRequestItems.size) {
|
|
319
|
+
this.onDidChangeSignInCountEmitter.fire(this.signInRequestItems.size);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async requestNewSession(providerId: string, scopes: string[], extensionId: string, extensionName: string): Promise<void> {
|
|
324
|
+
let provider = this.authenticationProviders.get(providerId);
|
|
325
|
+
if (!provider) {
|
|
326
|
+
// Activate has already been called for the authentication provider, but it cannot block on registering itself
|
|
327
|
+
// since this is sync and returns a disposable. So, wait for registration event to fire that indicates the
|
|
328
|
+
// provider is now in the map.
|
|
329
|
+
await new Promise<void>((resolve, _) => {
|
|
330
|
+
this.onDidRegisterAuthenticationProvider(e => {
|
|
331
|
+
if (e.id === providerId) {
|
|
332
|
+
provider = this.authenticationProviders.get(providerId);
|
|
333
|
+
resolve(undefined);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (provider) {
|
|
340
|
+
const providerRequests = this.signInRequestItems.get(providerId);
|
|
341
|
+
const scopesList = scopes.sort().join('');
|
|
342
|
+
const extensionHasExistingRequest = providerRequests
|
|
343
|
+
&& providerRequests[scopesList]
|
|
344
|
+
&& providerRequests[scopesList].requestingExtensionIds.indexOf(extensionId) > -1;
|
|
345
|
+
|
|
346
|
+
if (extensionHasExistingRequest) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const menuItem = this.menus.registerMenuAction(ACCOUNTS_SUBMENU, {
|
|
351
|
+
label: nls.localizeByDefault('Sign in with {0} to use {1} (1)', provider.label, extensionName),
|
|
352
|
+
order: '1',
|
|
353
|
+
commandId: `${extensionId}signIn`,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
const signInCommand = this.commands.registerCommand({ id: `${extensionId}signIn` }, {
|
|
357
|
+
execute: async () => {
|
|
358
|
+
const session = await this.login(providerId, scopes);
|
|
359
|
+
|
|
360
|
+
// Add extension to allow list since user explicitly signed in on behalf of it
|
|
361
|
+
const allowList = await readAllowedExtensions(this.storageService, providerId, session.account.label);
|
|
362
|
+
if (!allowList.find(allowed => allowed.id === extensionId)) {
|
|
363
|
+
allowList.push({ id: extensionId, name: extensionName });
|
|
364
|
+
this.storageService.setData(`authentication-trusted-extensions-${providerId}-${session.account.label}`, JSON.stringify(allowList));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// And also set it as the preferred account for the extension
|
|
368
|
+
this.storageService.setData(`authentication-session-${extensionName}-${providerId}`, session.id);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
const previousSize = this.signInRequestItems.size;
|
|
373
|
+
if (providerRequests) {
|
|
374
|
+
const existingRequest = providerRequests[scopesList] || { disposables: [], requestingExtensionIds: [] };
|
|
375
|
+
|
|
376
|
+
providerRequests[scopesList] = {
|
|
377
|
+
disposables: [...existingRequest.disposables, menuItem, signInCommand],
|
|
378
|
+
requestingExtensionIds: [...existingRequest.requestingExtensionIds, extensionId]
|
|
379
|
+
};
|
|
380
|
+
this.signInRequestItems.set(providerId, providerRequests);
|
|
381
|
+
} else {
|
|
382
|
+
this.signInRequestItems.set(providerId, {
|
|
383
|
+
[scopesList]: {
|
|
384
|
+
disposables: [menuItem, signInCommand],
|
|
385
|
+
requestingExtensionIds: [extensionId]
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
if (previousSize !== this.signInRequestItems.size) {
|
|
390
|
+
this.onDidChangeSignInCountEmitter.fire(this.signInRequestItems.size);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
getLabel(id: string): string {
|
|
396
|
+
const authProvider = this.authenticationProviders.get(id);
|
|
397
|
+
if (authProvider) {
|
|
398
|
+
return authProvider.label;
|
|
399
|
+
} else {
|
|
400
|
+
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
supportsMultipleAccounts(id: string): boolean {
|
|
405
|
+
const authProvider = this.authenticationProviders.get(id);
|
|
406
|
+
if (authProvider) {
|
|
407
|
+
return authProvider.supportsMultipleAccounts;
|
|
408
|
+
} else {
|
|
409
|
+
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
async getSessions(id: string, scopes?: string[], user?: AuthenticationSessionAccountInformation): Promise<ReadonlyArray<AuthenticationSession>> {
|
|
414
|
+
const authProvider = this.authenticationProviders.get(id);
|
|
415
|
+
if (authProvider) {
|
|
416
|
+
return authProvider.getSessions(scopes, user);
|
|
417
|
+
} else {
|
|
418
|
+
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
async login(id: string, scopes: string[], options?: AuthenticationProviderSessionOptions): Promise<AuthenticationSession> {
|
|
423
|
+
const authProvider = this.authenticationProviders.get(id);
|
|
424
|
+
if (authProvider) {
|
|
425
|
+
return authProvider.createSession(scopes, options || {});
|
|
426
|
+
} else {
|
|
427
|
+
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async logout(id: string, sessionId: string): Promise<void> {
|
|
432
|
+
const authProvider = this.authenticationProviders.get(id);
|
|
433
|
+
if (authProvider) {
|
|
434
|
+
return authProvider.removeSession(sessionId);
|
|
435
|
+
} else {
|
|
436
|
+
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async signOutOfAccount(id: string, accountName: string): Promise<void> {
|
|
441
|
+
const authProvider = this.authenticationProviders.get(id);
|
|
442
|
+
if (authProvider) {
|
|
443
|
+
return authProvider.signOut(accountName);
|
|
444
|
+
} else {
|
|
445
|
+
throw new Error(`No authentication provider '${id}' is currently registered.`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export interface AllowedExtension {
|
|
451
|
+
id: string;
|
|
452
|
+
name: string;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export async function readAllowedExtensions(storageService: StorageService, providerId: string, accountName: string): Promise<AllowedExtension[]> {
|
|
456
|
+
let trustedExtensions: AllowedExtension[] = [];
|
|
457
|
+
try {
|
|
458
|
+
const trustedExtensionSrc: string | undefined = await storageService.getData(`authentication-trusted-extensions-${providerId}-${accountName}`);
|
|
459
|
+
if (trustedExtensionSrc) {
|
|
460
|
+
trustedExtensions = JSON.parse(trustedExtensionSrc);
|
|
461
|
+
}
|
|
462
|
+
} catch (err) {
|
|
463
|
+
console.error(err);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return trustedExtensions;
|
|
467
|
+
}
|