Compare commits

..

472 Commits

Author SHA1 Message Date
Cheena Malhotra
22f384e569 Bump STS (#22355) 2023-03-16 21:35:38 -07:00
Cheena Malhotra
d9ba75a1a5 MSAL cache encryption + log improvements (#22335) (#22354)
# Conflicts:
#	extensions/mssql/config.json
2023-03-16 18:48:08 -07:00
Alan Ren
d162d0a00f update the display name (#22345) (#22349) 2023-03-16 12:12:15 -07:00
Aasim Khan
6579de5803 Fixing new connections not expanding in object explorer. (#22307) (#22325)
* Fixing new connection node not expanding in OE

* Fixing new connections not expanding and fixing expand request not resolving because of some provider error.

* Fixing test

* Adding a setting for node expansion timeout

* Not saving when loading tree based connections

* Adding some logs

* Removing special casing for mssql provider

* Missing providers

* Adding user toast for node expansion timeout

* Adding notification service to test

* Fixing node type for mssql

* remove polling

* Fixing onNodeStatus

* Fixing stuff

* consolidating functions

* Consolidating resolve logic

* removing extra try catch

* code cleanup

* adding size checks

* Removing commented code

* Ignoring errors from other sessions and nodepaths.
2023-03-14 13:22:57 -07:00
Karl Burtram
dc8e4414ff Fix casing of OE icon files to match source (#22315) (#22316) 2023-03-14 11:17:05 -07:00
Alex Ma
4d51ccb41e Fix for Edit Data grid newline on multiline strings (#22269) (#22289)
* Fix for newline replacement

* added proper null regex and null character check

* removed cell class

* removed unnecessary function

* revert back to old check

* change onbeforeeditcell

* small fix to typo in onBeforeEditCell

* made changes based on feedback

* added comments clarifying isDBCellValue
2023-03-09 17:43:24 -08:00
Karl Burtram
d05095ca82 Update STS to 4.5.1.4 (#22290) 2023-03-09 16:25:26 -08:00
Kim Santiago
ae31ba8b09 undo remove project change in data workspace (#22283) (#22286) 2023-03-09 14:50:38 -08:00
Cheena Malhotra
4cc1ddfc28 Include App Path in service launch arguments (#22233) (#22256)
# Conflicts:
#	extensions/mssql/config.json
2023-03-09 05:23:31 -08:00
Karl Burtram
df557a8dbe Bump STS to 4.5.1.3 in release/1.42 (#22254) 2023-03-08 19:28:41 -08:00
Aasim Khan
7a9287be0b Fixing icon for group by schema (#22212) (#22240) 2023-03-08 13:06:44 -08:00
Aasim Khan
6ee5eb2104 Fixing execution plan not finding provider (#22238) (#22241) 2023-03-08 13:06:27 -08:00
Alan Ren
6b6a8c422d remove commands (#22218) (#22224) 2023-03-08 11:07:54 -08:00
Kim Santiago
d013b295b7 add sql project commands to data workspace activation events (#22198) 2023-03-07 14:28:34 -08:00
Alex Ma
fb50a7dbb7 [Loc] Massive fix for March Langpack (#22182) 2023-03-07 13:58:31 -08:00
Hai Cao
f70897cd4d bump STS to pick up login changes (#22195) 2023-03-07 12:28:14 -08:00
Charles Gagnon
c637b81d4d Fix telemetry property names (#22190) (#22193)
(cherry picked from commit a575eb1b87)
2023-03-07 09:25:20 -08:00
Karl Burtram
7d712e71eb Update STS to pickup user changes (#22185) 2023-03-06 21:59:22 -08:00
Karl Burtram
f21709c09f Only support 'user with login' in dialog (#22175) (#22177) 2023-03-06 15:24:40 -08:00
Alan Ren
2a4cb4ce08 disable the checkbox for schemas owned by user (#22178) (#22183) 2023-03-06 15:24:18 -08:00
Alex Hsu
c882aeddb0 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230306164853268. (#22167) 2023-03-06 09:24:16 -08:00
Alex Hsu
fae37856fb Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230305164151174. (#22153) 2023-03-05 11:23:06 -08:00
Alex Ma
666034b85c [Loc] updates to xlfs 3-5-2023 (#22152) 2023-03-05 05:04:27 -08:00
Alex Hsu
720f91b0ea Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230304164235493. (#22150) 2023-03-05 03:04:28 -08:00
Aasim Khan
644f5a16ef Fixing URI openings for execution plans (#22139) 2023-03-04 15:14:50 -08:00
Alan Ren
b5a9a3647b escape the special character (#22141) 2023-03-03 23:57:40 -08:00
Lewis Sanchez
0f813a9900 Update add account icon (#22142)
* Update add account icon

* Remove unused icon from SqlIconId

* Remove unused accountActions.css

* Revert "Remove unused accountActions.css"

This reverts commit d31d17f5d2027f25f306e713abff14e750e7479a.

* Remove unused css file and svg's

* Remove unused import

* Revert "Remove unused import"

This reverts commit 91ad47da56d428d8805b65f685af76694b16ba6c.

* Remove unused import
2023-03-03 17:42:10 -08:00
Kim Santiago
5fef212ea3 add vscode mssql handling for getSqlProjectsService() (#22121)
* add vscode mssql handling for getSqlProjectsService()

* try to fix error because of projectStyle enum
2023-03-03 16:52:05 -08:00
Alan Ren
d2d24e3827 dispose view after the operation is done (#22144) 2023-03-03 15:34:51 -08:00
Cheena Malhotra
07eb964c32 Fix AuthLibrary detection and use MSAL by default (#22140) 2023-03-03 14:33:29 -08:00
Alex Ma
076ab355a0 Langpack update for March 1.43 release (#22137)
* [Loc] Update to langpack source files and xlfs for March Release

* Last update before code complete
2023-03-03 13:54:13 -08:00
Cheena Malhotra
aa350f7e49 Enable SQL Auth Provider support (#21903) 2023-03-03 12:49:01 -08:00
Cheena Malhotra
0ac6f40559 Fixes clearing of username/password on auth type change (#22138) 2023-03-03 12:45:09 -08:00
Cheena Malhotra
19d77f02dd Pre-populate username for selected user account (AzureMFAAndUser) (#22126) 2023-03-03 12:11:52 -08:00
Alan Ren
9ea3889170 use native osx_arm64 sts bits (#22122)
* use native osx-arm64 sts bits

* universal app

* update package
2023-03-03 11:09:39 -08:00
Benjin Dubishar
1a5ae9cf32 Bumping SqlToolsService to 4.5.0.38, and adding new bindings (#22129)
* Bump STS

* adding/updating bindings
2023-03-03 09:13:16 -08:00
Alex Hsu
1cc338c79b Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230303164110539. (#22136) 2023-03-03 08:52:15 -08:00
AkshayMata
bb40a71166 Update migration service (#22135)
This PR bumps up the Migration Service version to 4.5.0.38. This version includes login migration nuget changes to expose error codes to the user.
2023-03-03 08:35:57 -08:00
Alan Ren
1882c02ad6 update the compiled js file (#22123) 2023-03-03 08:06:29 -08:00
Alex Ma
18758b6748 [Loc] update to Azurecore and SQL xlfs (#22130) 2023-03-03 00:02:58 -08:00
Cheena Malhotra
b310e3eed4 Fixes a console error raised from error dialog action (#22124) 2023-03-02 21:02:31 -08:00
Cheena Malhotra
375ce82b7d Bump STS (#22119) 2023-03-02 18:42:01 -08:00
Charles Gagnon
bd797ea6e1 Update extension privacy statements (#22120)
* Update extension privacy statements

* one more
2023-03-02 16:39:29 -08:00
Lewis Sanchez
eb3c5f1f47 Moves New Deployment from connections pane to file menu bar. (#22090)
* Moves New Deployment to file menu bar.

* Add deployment back to breadcrumb menu

* Update extensions/resource-deployment/DEVELOPER_GUIDE.md

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Adjust new deployment mnemonic

* Remove unused localized string

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-03-02 16:26:38 -08:00
Christopher Suh
20c290aa91 Better error messages from connection failures in MSAL (#22065)
* better error messages from connection failures in MSAL\, fix typo

* cleanup

* pr comments

* rename error interface

* address pr comments

* update api

* fix typings

* change one more typing

* fix build

* fix tests
2023-03-02 15:38:12 -08:00
Charles Gagnon
6172b4677f Update ads-extension-telemetry (#22112) 2023-03-02 15:20:04 -08:00
Alex Ma
69d3552749 [Loc] xlf update for 3-2-2023 (#22117) 2023-03-02 15:17:50 -08:00
Alan Ren
9b6018a21e fix null reference issue (#22113)
* fix null reference issue

* move opendialog call out of promise.
2023-03-02 14:44:10 -08:00
Raymond Truong
da92875fea vbump MigrationService (#22110) 2023-03-02 14:43:35 -08:00
Benjin Dubishar
df9b0f7771 Adding sqlproj property bindings (#22106) 2023-03-02 13:34:00 -08:00
Cory Rivera
075b3cb35e Remove unused $connect arg leftover from vscode notebooks change. (#22108) 2023-03-02 13:26:44 -08:00
Raymond Truong
8600cc3cd1 [SQL Migration] Remove preview tag from SQL DB scenario (#22070)
* Remove preview from strings

* Update readme
2023-03-02 13:11:46 -08:00
Alan Ren
91ee26a888 use native win-arm64 STS builds (#22103)
* use native windows arm STS

* update downloader and build job

* remove workarounds

* vbump STS

* revert change

* update ads-service-downloader version

* fix admin-tool-ext-win extension
2023-03-02 12:37:14 -08:00
Hai Cao
20969bf244 Add perf marks for query execution (#22082) 2023-03-02 11:36:29 -08:00
Aasim Khan
9033ed5583 Adding group by schema button to OE (#22083) 2023-03-02 11:35:33 -08:00
brian-harris
345c6b16e3 add error handler for validateIR gateway timeout (#22091)
* add error handler for validateIR gateway timeout

* log api errors
2023-03-02 11:01:28 -08:00
Benjin Dubishar
711923cd46 Adding None bindings to the sqlProjects service (#22085)
* Adding None bindings

* updating names of None bindings
2023-03-01 22:02:54 -08:00
Alex Ma
dacbc24143 [Loc] small fix to Portuguese lcl file (#22088)
* [Loc] small fix to Portuguese lcl file

* remove newline
2023-03-01 17:14:51 -08:00
Alex Ma
e06e88cc0f [Loc] update to mssql and sql-migration xlf files (#22087) 2023-03-01 16:58:29 -08:00
Charles Gagnon
d0ca3031e0 Fix query-history README images (#22084) 2023-03-01 14:36:40 -08:00
Charles Gagnon
e4663b9778 Update extension READMEs (#22079) 2023-03-01 11:34:17 -08:00
Cheena Malhotra
35f7736b96 Add Secure Enclaves dropdown with customizable Advanced options (#22019) 2023-03-01 11:01:50 -08:00
AkshayMata
bf05ea69ef [SQL-Migration] Login migrations telemetry (#22038)
This PR enhances telemetry for login migrations (and in the following ways:

Add details for starting migration (number of logins migrating, type of logins)
Log Migration result (number of errors per step, duration of each step, type of logins, if system error occurred)
Add sql-migration extension to our telemetry
Adds details when trying to connect to target
Tracks clicking "done" from the wizard
Fixes bucketizing for navigating telemetry in the login migration wizard
Sample usage of kusto query for new telemetry:
RawEventsADS
| where EventName contains 'sql-migration'
| extend view = tostring(Properties['view'])
| extend action = tostring(Properties['action'])
| extend buttonPressed = tostring(Properties['buttonpressed'])
| extend pageTitle = tostring(Properties['pagetitle'])
| extend adsVersion = tostring(Properties['common.adsversion'])
| extend targetType = tostring(Properties['targettype'])
| extend tenantId = tostring(Properties['tenantid'])
| extend subscriptionId = tostring(Properties['subscriptionid'])
| where view contains "login"
//| where adsVersion contains "1.42.0-insider"
| where ClientTimestamp >= ago(18h)
| project EventName, ClientTimestamp, SessionId, view, pageTitle, action, buttonPressed, targetType
, tenantId, subscriptionId
, adsVersion, OSVersion, Properties
2023-03-01 10:55:01 -08:00
Kim Santiago
d6358b3e29 Add telemetry events for rename and move in sql project (#22068)
* add telemetry events for rename and move in sql project

* remove check

* update telemetry events
2023-03-01 10:25:09 -08:00
AkshayMata
e69346e7fa Update infobox to public preview (#22074)
This PR updates the infobox for upcoming public preview mode.
2023-03-01 09:48:30 -08:00
Benjin Dubishar
eecffbf82d Bump SqlToolsService to 4.5.0.33 (#22076) 2023-03-01 09:19:14 -08:00
Alan Ren
6684e227d6 Fix default install location for system installer of Windows on ARM build (#22073)
* fix default path for win arm system installer

* update

* remove commented out code
2023-03-01 08:49:29 -08:00
Charles Gagnon
4a5ac92e46 Update ads-extension-telemetry to 1.4.0 (#22069)
* Update ads-extension-telemetry

* One more
2023-02-28 22:25:07 -08:00
Alex Ma
78b285e43a [Loc] update to mssql and sql-database-projects xlfs (#22072) 2023-02-28 17:27:11 -08:00
Kim Santiago
bc85f52dd4 Update sql project file move to use DacFx api (#22064)
* update move to use STS api

* swap rename to use move function

* add try catch

* remove debug statement

* get original path from node
2023-02-28 14:31:49 -08:00
Cory Rivera
2ca093f15f Disable the vscode SQL notebook controller since it breaks query editor. (#22061) 2023-02-28 12:18:38 -08:00
Kim Santiago
0413b95343 Swap rename to use DacFx move api (#22051)
* swap rename to use DacFx project apis

* add support for rename pre/post deploy scripts and add tests

* update the enum names too

* check instanceof instead of getting and iterating through all the collections
2023-02-28 11:59:09 -08:00
Kim Santiago
8550faaa73 Have different node types for the different item types in sql project tree (#22053)
* Have different node types for the different item types in sql project tree

* address comments
2023-02-28 10:31:46 -08:00
Aasim Khan
555f8fbb1e Adding null checks to prevent runtime exceptions (#22054) 2023-02-27 23:46:14 -08:00
Aasim Khan
45d41347ba Adding null checks and fixing values in slickgrid checkbox column plugin (#22050)
* Adding null checks to checkbox column

* Setting default value for undefined checkbox
2023-02-27 18:52:16 -08:00
Alex Ma
7d4ee2d0b8 [Loc] update to SQL-Database-Projects XLF for 2-27-2023 (#22052) 2023-02-27 17:00:38 -08:00
Kim Santiago
e675fc14f0 Revert 'Add profile section in Publish project UI (#21906)' (#22047)
This reverts commit cb58286247.
2023-02-27 15:09:50 -08:00
Benjin Dubishar
febfe3718f Adding bindings for SqlProject service getters (#22046)
* Getters

* blank lines

* STS bump

* Fixing typos

* updating contract ID
2023-02-27 15:01:04 -08:00
Alan Ren
d48984fe13 use the dialog's loading indicator (#22032)
* use the dialog's loading indicator

* more

* comments
2023-02-27 13:13:16 -08:00
Cory Rivera
73f00b63ce Open books in VS Code notebooks if the setting is enabled. (#22031) 2023-02-27 11:54:35 -08:00
Aasim Khan
dbd1c1b5b3 Fixing table being announced for button (#22024)
* Fixing table being announced for button

* Fixing issue in the component

* Reverting other changes
2023-02-27 11:24:58 -08:00
Aasim Khan
4fd6a57afc Adding aria label (#22030) 2023-02-27 10:43:15 -08:00
Alex Hsu
23560a8744 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230227163924260. (#22041) 2023-02-27 09:33:15 -08:00
Alex Hsu
1e8519d54a Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230226165412143. (#22040)
Co-authored-by: Karl Burtram <karlb@microsoft.com>
2023-02-26 12:29:59 -08:00
Alex Hsu
62b90c41ff Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230225164521545. (#22035) 2023-02-26 12:22:58 -08:00
AkshayMata
d39e503788 [SQL-Migration] Fix JSON-RPC Migration crash on ADS reload due to zombie process (#22036)
This PR fixes an issue where the JSON-RPC Migration Service crashes when ADS is reloaded.

This situation applies when user tried to reload ADS where SQL-migration extension was running:

when connecting to DB, SQL-migration extension loads and migration service launches
if a previous MigrationService zombie process is stil running (if extension was used before), then that zombie process will have a lock on the log file
new launches of MigrationService on reloaded ADS fails b/c it can't obtain log file handle due to lock in step 2
The fix stops the MigrationService on extension deactivate and will ensure that a zombie MigrationService process isn't hanging around on reloads.

No hotfix needed as 1.4.0 was baking in insiders and has not been released to stable yet. Additionally, this mainly affects developers as they are most likely to reload ADS this way. Caveat: users do need to reload after installing latest version, however they will not hit this code path (since the migration service process is only in new versions of the extension)
2023-02-25 19:28:36 -08:00
Alex Ma
8752ba434d [Loc] update to data-workspace xlf (#22034) 2023-02-24 21:09:12 -08:00
Kim Santiago
7a8888f073 Show error if trying to create or open project when no project extension is installed (#22021)
* show error if trying to create or open project when no project extensions are found

* only check if project providers are available on startup and when extensions change

* addressing comments

* Update extensions/data-workspace/src/services/workspaceService.ts

use some instead of find

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-02-24 13:36:39 -08:00
Alex Hsu
d5c5b3451a Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230224164330029. (#22027) 2023-02-24 12:54:50 -08:00
Charles Gagnon
703f97a7bf Remove kburtram-query-plan (#22017)
* Remove kburtram-query-plan

* distro

* distro2
2023-02-24 09:12:04 -08:00
AkshayMata
a9166194cb Update migration service to 4.5.0.28 (#22020)
This PR updates the JSON-RPC Migration service to the latest version. Critically, it also changes the dotnet version to 7.0. The STS dotnet version was recently changed, which changed the names of the release packages and broke our existing links.
2023-02-24 08:57:06 -08:00
Alex Ma
8715f2bdb4 [Loc] small change to sql-database-projects xlf (#22026) 2023-02-24 04:11:10 -08:00
Sakshi Sharma
41e2767880 Add publish profile to sql proj and tree (#22008)
* Read publish profiles stored in sqlproj file and present it in the projects tree

* Save publish profile and add it to sqlproj file, and present it in the tree

* Fix context menu operations

* Add tests

* Address comments
2023-02-23 22:32:12 -08:00
Alex Ma
91cdd610fd [Loc] update to xlfs for 2-23-2023 (#22023) 2023-02-23 17:30:48 -08:00
Kim Santiago
d75cf2b657 Hookup sqlcmdvar delete (#22018)
* delete sqlcmd variable working

* undo add

* add test
2023-02-23 16:44:08 -08:00
Cory Rivera
f53119c2a6 Enable VS Code notebooks with a built-in SQL kernel. (#21995) 2023-02-23 16:22:46 -08:00
Charles Gagnon
290687a207 Remove unused things from ads telemetry service (#22016) 2023-02-23 15:34:47 -08:00
Kim Santiago
4ed1ef34b6 update version of Microsoft.Build.Sql used for building legacy sql projects (#22010) 2023-02-23 15:12:09 -08:00
Christopher Suh
b7e0bbb64a Update api to pass more detailed error messaging from azurecore (#22003)
* update api to pass more detailed error messaging from azurecore

* fix formatting

* fix buid error

* fix pr comments

* move to azdata.proposed.d.ts

* pr comments

* Update extensions/azurecore/src/account-provider/auths/azureAuth.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* refactor

* pr comments

* Update src/sql/workbench/services/accountManagement/browser/accountManagementService.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* pr comments

* Update src/sql/azdata.proposed.d.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update extensions/azurecore/src/account-provider/auths/azureAuth.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* fix formatting

* fix compile error

* fix compile error

* pr comments

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-02-23 13:00:18 -08:00
Raymond Truong
85056fb1b7 [SQL Migration] Allow folders inside blob containers (#21952)
* WIP

* WIP

* WIP - add new property to blob

* Add error messages

* Fix undefined for offline scenario

* Add support for offline scenario

* Clean up

* vbump extension

* remove >1 level deep folders

* fix [object] object issue

* Remove unnecessary asyncs

* don't allow >1 level deep for offline scenario lastBackupFile
2023-02-23 10:40:56 -08:00
Alex Hsu
fd282cd20b Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230223164743768. (#22012) 2023-02-23 09:40:38 -08:00
Benjin Dubishar
0354775107 Fleshing out the SqlProjects service bindings (#21984)
* starts of sqlprojectsservice

* copy to mssql

* adding all the boilerplate

* updating service call structures

* Fixing up test mocks

* Adding comments to all the bindings

* blank space

* swapping for Promise; adding vscode-mssql type bindings

* patching
2023-02-22 22:58:30 -08:00
Lewis Sanchez
872095ed84 Hide refresh button on disconnected connections (#22009) 2023-02-22 16:41:07 -08:00
Kim Santiago
169138e24b Remove data workspace * activationEvent (#22005)
* remove data workspace * activationEvent

* fix tests
2023-02-22 12:03:39 -08:00
Kim Santiago
10c3199a23 update sql projects azdata dependency (#22007) 2023-02-22 11:11:35 -08:00
Aasim Khan
c3e0478447 Adding aria role to hyperlink cell in slickgrid (#21998)
* Adding aria role to hyperlink

* Adding default
2023-02-22 10:42:11 -08:00
Lewis Sanchez
656a86a103 Fix empty connection name in delete connection prompt (#22001)
* Fix empty name in delete connection prompt

* Update src/sql/workbench/services/objectExplorer/browser/connectionTreeAction.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-02-21 17:43:29 -08:00
Alex Ma
ee60319f70 [Loc] update to strings for 2-21-2023 for data workspace and sql-database-projects (#22002) 2023-02-21 16:50:28 -08:00
Kim Santiago
a7f68ebd33 Drag and drop support for sql projects tree (#21956)
* Drag and drop working

* update comment

* move to projectController

* remove registerTreeDataProvider

* add tests

* fix dragging to project root

* cleanup

* addressing comments
2023-02-21 15:45:25 -08:00
Lewis Sanchez
effdf4f538 Stops Azure connection with the "Do not save" server group option from being stored in the default server group list. (#21997)
* Fix Azure connections do not save to server group error

* Revert unnecessary change
2023-02-21 13:47:40 -08:00
Alex Ma
004d55d98d [Loc] update to MSSQL xlf (#21999) 2023-02-21 13:19:03 -08:00
Charles Gagnon
00493d6555 Add telemetry section to extension READMEs (#21994)
* Add telemetry section to extension READMEs

* Add separate links for VS Code
2023-02-21 12:34:17 -08:00
Charles Gagnon
29049bb15e Add Codeowners for import and sql-migration (#21996) 2023-02-21 12:31:55 -08:00
Kim Santiago
7761c3b171 Swap create new project api for sql projects (#21971) 2023-02-21 10:00:56 -08:00
Alex Hsu
66edf059be Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230218164737005. (#21986) 2023-02-19 08:15:34 -08:00
Aasim Khan
22c3829225 Adding setting for OE expansion timeout (#21985)
* Adding setting for OE expansion timeout

* Cleaning up the names

* Adding minimum timeout value
2023-02-17 23:02:57 -08:00
Alan Ren
b5ce7af090 Add support for Login and User management (#21981)
* initial commit

* leave only march release objects

* clean up

* login dialog

* localize and use background operation

* code cleanup

* remove tab

* support server role in login

* remove canEditName

* add user support

* comments and bug fixes

* remove hasDBAccess for now

* refactoring

* fix error

* user dialog UI

* telemetry, error handling and refactoring

* Fix references to dialogInfo (#21914)

* update telemetry

* Bump STS and use actual object management service

* add preview and handle no-change scenario

* fix merge issue

---------

Co-authored-by: Karl Burtram <karlb@microsoft.com>
2023-02-17 18:02:31 -08:00
Christopher Suh
6231df85e0 Handle undefined error when opening connection dialog (#21980)
* handle undefined error when opening connection dialog

* combine into else if

* change log

* update log message
2023-02-17 15:22:51 -08:00
Lewis Sanchez
7c47aea06e Fix set authenticationType of undefined error (#21982) 2023-02-17 15:04:59 -08:00
Aasim Khan
e40c8dda25 Removing migration contracts from mssql (#21966)
* Removing migration contracts from sts

* Update sts

* Pushing latest sts
2023-02-17 13:50:53 -08:00
brian-harris
9b841f4a49 fix bug in dropdown auto-selection (#21977) 2023-02-17 12:06:16 -08:00
Alex Hsu
4852de7b8e Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230217164703043. (#21976) 2023-02-17 11:56:24 -08:00
Cheena Malhotra
66053f5152 Fix missing null ref check causing extension issues (#21974) 2023-02-17 09:45:23 -08:00
Kim Santiago
c5fc37c373 Initial changes for adding SqlProjectsService (#21967)
* Add SqlProjectsService

* cleanup

* reorder imports

* undo changes in project.ts for now to fix tests
2023-02-16 17:15:24 -08:00
Sakshi Sharma
199f280586 Populate dbs properly when using publish profile, change connection icon and try enabling buttons (#21968) 2023-02-16 16:14:40 -08:00
Sakshi Sharma
7c6ae87fc8 Read server options from publish profile (#21960)
* Read encrypt and trust server certificate

* Set hostname in certificate setting

* Address comment- open connection dialog if the connection string in publish profile doesn't load a connection, instead of throwing an error.
2023-02-16 16:12:43 -08:00
Alex Hsu
f25c250547 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230216164409169. (#21963) 2023-02-16 08:55:38 -08:00
Alan Ren
32c7a4aeec add tab navigation option for slickgrid (#21947)
* profiler a11y bug fixes

* add new option

* replace old implementation

* update slickgrid
2023-02-15 21:37:01 -08:00
Alan Ren
8690c350d2 fix server group color a11y issue (#21958) 2023-02-15 21:21:35 -08:00
Aasim Khan
48d0aa72cc Replacing select with focus in OE (#21954) 2023-02-15 17:27:36 -08:00
Alex Ma
69616cd221 [Loc] update to mssql and sql xlf files (#21957) 2023-02-15 16:48:28 -08:00
Aasim Khan
d6c35836cc Adding group by schema to OE (#21941)
* Adding group by schema and updating schema icon

* Adding item context menu

* Fixing command logic

* Adding telemetry for group by and changing default config

* reverting no child nodes error message

* Code cleanup

* Cleaning up constants

* Removing unused imports

* Update extensions/mssql/src/main.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* converting to sendActionEvent

* sendActionEvent

* Adding telemetryViews and telemetry actions

* Fixing localized string

* registering context

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-02-15 15:18:10 -08:00
Cory Rivera
f7fa9bece3 Add a check for an undefined model when creating the connection dialog model. (#21953) 2023-02-15 14:23:15 -08:00
Alex Hsu
de5e81a157 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230215164641972. (#21943) 2023-02-15 12:54:51 -08:00
Lucy Zhang
498f278887 Add horizontal scrollbar to Kqlmagic table and remove plotly graph max width (#21934)
* add scroll and remove plotly max width

* scope down
2023-02-15 10:40:45 -08:00
Lewis Sanchez
d9b24522e5 Fix missing password in Connection pane for Server connections with remembered passwords (#21813)
* Fix missing password in Connection pane

* Get saved password for SQL login default auth type

* Clean up

* Fix build hygiene errors

* Captures input

* Add timeout waiting for all promises to resolve

* Add missing semicolon

* Code review feedback

* Minor clean up

* Code review feedback

* Improved error messaging

* Update src/sql/workbench/services/connection/browser/connectionDialogService.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Improves UX around loading passwords

* Remove unused import

* Uses await instead of promise chaining.

* Removes async

* Revert back to resolving password promise.

* Asserts controller map and model have values.

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-02-14 20:49:55 -08:00
Alan Ren
a683b1b777 profiler a11y bug fixes (#21940) 2023-02-14 18:48:17 -08:00
Alan Ren
447a9d0f34 fix the find widget hide issue (#21937) 2023-02-14 18:19:40 -08:00
Kim Santiago
4f6fe5955d Remove parent from sql project tree items (#21912)
* update getFileProjectEntry and getRelativePath

* remove root and fix tests

* remove parent from sql project tree items
2023-02-14 14:53:39 -08:00
Kim Santiago
fe25674401 change sqlprojUri to projectFileUri (#21938) 2023-02-14 13:56:02 -08:00
Kim Santiago
71c12883fe Remove references to root in sql projects (#21911)
* update getFileProjectEntry and getRelativePath

* remove root and fix tests
2023-02-14 10:34:46 -08:00
Kim Santiago
d5384cad0e Fix database name in dacpac wizard not saying required (#21932) 2023-02-14 09:50:52 -08:00
AkshayMata
5e7446af6c Refactor functionality into LoginMigrationsModel (#21933)
This PR refactors to encapsulate all login migration functionality into LoginMigrationModel
2023-02-14 06:05:53 -08:00
Alan Ren
385e4a2245 move the focus to newly added filter field. (#21930) 2023-02-13 19:43:16 -08:00
Alan Ren
a754d235c0 completely hide the hidden widget (#21931) 2023-02-13 19:42:34 -08:00
Alex Ma
f678e27515 [Loc] update to XLFS for 2-13-2023 (#21929) 2023-02-13 16:13:24 -08:00
Sakshi Sharma
cb58286247 Add profile section in Publish project UI (#21906)
* Add profile section in Publish project UI

* Move publish profile row below Publish Target

* Add contract for savePublishProfie and SaveProfileAs button functionality

* Make the DacFx contract functional

* Send values from UI to DacFx service call

* Fix build error

* Address comment, remove print statements

* Address comments

* Set correct connection string
2023-02-13 14:06:42 -08:00
Alan Ren
93f5581bc7 add aria-label for step link in wizard (#21925)
* add aria label to wizard step link

* update aria label
2023-02-13 13:41:01 -08:00
Alex Hsu
97ff0694b2 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230213164318709. (#21921) 2023-02-13 08:56:23 -08:00
Alex Hsu
882a7342e0 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230212165154337. (#21917) 2023-02-12 10:26:47 -08:00
Aasim Khan
837236be0f Modifying the migration extension to use its own service. (#21781)
* Adding migration service to sql migrations

* enabling auto flush log

* Adding support for env variable

* Adding TDE Migration service

* code cleanup

* updating service downloader

* Removing custom output channel

* remove unnecessary await

* Updated service version to get latest code

* Consolidate TDE into migration service

* Sync to latest main

* Update sql-migration package version

* Fix merge conflict error

* Fixing all merge conflicts

* Fixing stuff

* removing extra whitespace

* Cleaning up

---------

Co-authored-by: Akshay Mata <akma@microsoft.com>
2023-02-12 09:59:09 -08:00
Alan Ren
12a3bf6b3b handle json (#21915) 2023-02-10 19:05:32 -08:00
Charles Gagnon
1d96476a81 Filter more command IDs (#21910)
* Filter more command IDs

* More
2023-02-10 14:41:17 -08:00
Kim Santiago
2b4c608b93 Update sql projects tree to use sqlproj uri instead of parent nodes (#21901)
* update sql projects tree to use sqlproj uri instead of parent nodes

* remove todo

* undo other change

* update a couple more
2023-02-10 11:22:59 -08:00
Cheena Malhotra
3fb8d57d25 Add support for Encrypt=Strict for TDS 8.0 connections with SQL Server 2022 (#21256) 2023-02-10 10:34:36 -08:00
Alex Hsu
c75628639c Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230210164036933. (#21907) 2023-02-10 09:30:18 -08:00
Alan Ren
514d599e62 remove client side sorting for db list (#21899)
* remove client side sorting for db list

* update sts
2023-02-10 09:15:41 -08:00
Cory Rivera
319e0811f1 Specify an editor ID for notebook inputs. (#21900) 2023-02-09 14:08:19 -08:00
Kim Santiago
0e269e0438 Cleanup sql projects tree (#21883)
* remove MessageTreeItem and rename projectUri to relativeProjectUri

* declare variables inline in constructor
2023-02-09 11:42:00 -08:00
Karl Burtram
37ad1b0fdb Update changelog for 1.41.2 (#21897)
* Update changelog for 1.41.2

* spelling
2023-02-09 10:56:35 -08:00
Alex Hsu
5b5705c03d Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230209164917683. (#21894) 2023-02-09 09:27:55 -08:00
Kim Santiago
f8d9106eef removing unused SqlDatabaseProjectTreeViewProvider functions (#21885) 2023-02-09 09:23:45 -08:00
Alan Ren
711bffb1f5 auto reveal only in dev mode (#21880) 2023-02-08 10:38:42 -08:00
Raymond Truong
480d8e2cd0 [SQL Migration] Properly respect user's encryptConnection and trustServerCertificate settings (#21824)
* WIP

* Always get latest current connection

* Update more references

* Clean up

* Clean up

* vbump

* Update comments

* Address PR feedback

* Separate into helper methods
2023-02-08 10:12:11 -08:00
Charles Gagnon
99a924dbcd Remove unused packages from MSSQL (#21871) 2023-02-07 19:22:44 -08:00
Alex Ma
dfe84da196 [Loc] update to xlfs for 2-7-2023 (#21873) 2023-02-07 16:51:54 -08:00
Kim Santiago
af8316291e Rename file support in sql projects (#21858)
* add quickpick for rename file/folder in sql project

* add comment

* make rename file actually do something

* add validation
2023-02-07 16:27:44 -08:00
Christopher Suh
7150257218 Fix Account Dialog with Multiple Providers (#21836)
* fix uncaught error in showSplitView

* fixed bugs around account dialog with multiple providers

* cleanup

* fix index out of bounds error

* Fire account list update after removing provider, other pr fixes
2023-02-07 15:00:47 -08:00
junierch
61ddf297f9 Adding SQL tools team recommendations (#21866) 2023-02-07 12:48:56 -05:00
Cheena Malhotra
66410edf02 Migrate cert validation error handling to mssql extension (#21829) 2023-02-07 09:21:35 -08:00
Kim Santiago
e1b35d266a Fix publish profile telemetry for ADS (#21860) 2023-02-06 17:12:30 -08:00
Alex Ma
3036b53647 [Loc] Sql-Database-Projects XLF update (#21861) 2023-02-06 16:38:47 -08:00
Kim Santiago
7efe4f9ce9 Remove data sources tree item from sql projects (#21842)
* remove data sources tree item from sql projects

* remove data sources node name
2023-02-06 14:48:26 -08:00
junierch
8de5efdf86 databases query updated (#21856) 2023-02-06 15:16:52 -05:00
Lucy Zhang
b3048213e8 Minor improvements in notebook edit mode handling (#21839)
* rename + remove duplicate calls

* only fire onCellEditModeChanged when changed
2023-02-06 10:42:19 -08:00
dependabot[bot]
2767ff819d Bump http-cache-semantics from 4.1.0 to 4.1.1 in /build/npm/gyp (#21847)
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-06 09:19:40 -08:00
Alex Hsu
6de89d9978 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230206164004959. (#21855)
Co-authored-by: Karl Burtram <karlb@microsoft.com>
2023-02-06 09:18:44 -08:00
Alex Hsu
7de6b9a296 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230205165241590. (#21849) 2023-02-06 09:14:35 -08:00
Alex Hsu
46fbb1c07f Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230204164312212. (#21846) 2023-02-06 09:14:00 -08:00
Alan Ren
ac0dc4ee76 only toggle when enabled (#21844) 2023-02-03 20:40:22 -08:00
Alex Ma
c13bd5c03f [Loc] removed clouds from Azurecore (#21841) 2023-02-03 16:53:17 -08:00
dependabot[bot]
5d496ec83b Bump http-cache-semantics from 4.1.0 to 4.1.1 in /build (#21828)
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-03 10:52:16 -08:00
dependabot[bot]
a0b02fe16c Bump http-cache-semantics from 4.1.0 to 4.1.1 (#21827)
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-03 10:51:38 -08:00
Alex Hsu
45a346cfc1 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230203163954985. (#21834) 2023-02-03 09:34:42 -08:00
AkshayMata
9f5f49e956 Fix connecting to MI login bug (#21821)
This PR fixes a regression for migration login for MI instances that was introduced in https://github.com/microsoft/azuredatastudio/pull/21776/files#diff-93c1a62583fa32d99f775b71ad27922cf31f660d10717ecc6966784306de1b6f.

After that change, support for MI would fail as MI server types were going into the Sql VM path in sqlutils because the underlying logic for isSqlServerVM() was returning wrong results.

The new approach uses the targetType set in StateMachine to extract the correct serverName for connection string based on the targetType.

Testing:
- Tested SQL VM login migration end to end
- Tested SQL MI login migration end to end


This change also bumps the sql-migration version to 1.3.0
2023-02-03 06:43:39 -08:00
Christopher Suh
8f638be687 remove germany and us national clouds (#21825) 2023-02-02 16:11:04 -08:00
Aasim Khan
95d4f130c6 Replacing select with focus to prevent second create session (#21811) 2023-02-02 15:07:05 -08:00
Alex Ma
f082ac2176 [Loc] update to the data-workspace xlf (#21823) 2023-02-02 14:49:23 -08:00
Sakshi Sharma
972312b3f5 Add validation for new file names for sql projects (#21601)
* Add validation for new file names for sql projects

* Addres comments and add validation for new project dialog

* Address comments

* Address comments on test

* Fix tests

* Remove extra error messages and rename file

* Address comments

* Fix tests

* Add test file back
2023-02-02 07:25:26 -08:00
Alex Ma
1071c6dfff [Loc] changes made to xlfs for 2-1-2023 (#21810) 2023-02-01 17:05:14 -08:00
Kim Santiago
cce794dd14 UI changes for add/edit/delete SQLCMD variables in sql projects (#21799)
* add edit command

* add and delete

* cleanup

* more cleanup
2023-02-01 15:06:07 -08:00
Alex Ma
a911044745 Removed deepcopy and remove credentials functions from utils (#21808) 2023-02-01 14:20:25 -08:00
Christopher Suh
51da512edb Fix Cloud Endpoints (#21805)
* replace hardcoded endpoints

* cleanup
2023-02-01 12:32:47 -08:00
Raymond Truong
95ce199d56 [SQL Migration][Hotfix] Remove parameter from IR validation (#21800)
* Remove encryptConnection from validateIR

* Use correct version

* vbump to 1.2.6 for insiders release
2023-02-01 11:33:07 -08:00
siyang yao
749f13d9bf [SQL-Migration] collation errorcode (#21797) 2023-02-01 11:23:21 -08:00
Cheena Malhotra
51751557b6 Revert changes in mainThreadConnectionManagement (#21802) 2023-02-01 00:52:38 -08:00
Kim Santiago
7a0790f365 remove external streaming job from sql project context menu (#21787) 2023-01-31 16:36:14 -08:00
Alex Ma
298402647d Added error handling service for providers (#21627)
* added prototype errorHandlerService

* added initial contracts

* Added WIP client sent request function

* added WIP signature for handleOtherError to resourceProviderService

* made some small fixes

* removed unnecessary resourceProviderId

* added updates to contracts and resourceProvider

* moved error codes to azdata proposed

* added connection type instead of profile

* added WIP handleOtherError code

* added fix for send

* added WIP change password function in resource provider

* added work in progress error handling thread

* added errorHandler interface

* added result error check

* renamed errorHandling namespace to diagnostics

* WIP rename of errorhandler

* light cleanup

* Bump json5 from 2.1.3 to 2.2.3 in /extensions/machine-learning (#21514)

Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Stops second invocation of createNewSession while expanding OE tree items on disconnected servers (#21437)

* Debounces second invocation while expanding OE tree items

* Minor clean up

* Adjusts debounce time

* Adding temp trace comments

* Adds missing semicolon

* Removes debouncer to stop 2nd newSession calls

* Removes temp trace comments

* Updates comment

Co-authored-by: Alan Ren <alanren@microsoft.com>

* Bump json5 from 2.1.3 to 2.2.3 in /extensions/admin-tool-ext-win (#21546)

Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fix resource endpoints to end with slash (#21540)

* Bump json5 from 2.1.3 to 2.2.3 in /extensions/azcli (#21543)

Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump json5 from 2.1.3 to 2.2.3 in /extensions/arc (#21544)

Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* renamed diagnostics service slightly

* registered service

* added work in progress diagnostics implementation

* small changes

* added new diagnostics exe

* Changes for Diagnostics Service (#21583)

Co-authored-by: Cheena Malhotra <cmalhotra@microsoft.com>

* WIP provider changes

* added changes for errorDiagnosticsService

* removed stuff from mssql.

* made fix to connectionManagementService

* added error catch

* added small changes

* more small changes made

* added small changes to handleOtherError

* moved changePassword to CMS

* added testErrorDiagnosticsService

* Added provider-based handling for change password/generic error handling. (#21662)

* WIP rework for error connection change

* added connectionProfileDuringError

* added working password reset

* added comments

* consolidated connection profile conversion

* added additionalObjects parameter.

* removed unnecessary error profile grab

* added comments

* added changes to parameters and comments

* added changes and params

* added handleConnectionErrorParam

* added more changes

* added async

* added params and more

* added many fixes

* added updated documentation

* added WIP password change dialog with await

* added error handling

* added comment

* added options as parameters

* cleaned up parameters

* added async

* added check fixes

* Added username to title

* added server name to dialog

* Added dialog changes

* Revert "Added dialog changes"

This reverts commit c2bdcd16f4a0dffdc643ef9cae1c1a20642ac512.

* Revert "added server name to dialog"

This reverts commit dbd22e80461b5a068643f0c2d6728adce4010978.

* Revert "Added username to title"

This reverts commit 6d936b4d5f97f9345f8ec2fdbbcf6b52df18820a.

* Revert "added check fixes"

This reverts commit f58081a5af3276766e2042b4d671455b18add9a7.

* Revert "added async"

This reverts commit dd1198e26ec7542ec51add0628f588361d674299.

* Revert "cleaned up parameters"

This reverts commit 51135c9f9db452104697483779d8df15b6430717.

* Revert "added options as parameters"

This reverts commit b167804a2410558bbe60042e017ae2c77af7697f.

* Revert "added comment"

This reverts commit 0ad37326a3e025e88f715e3f2547be6825597a8d.

* Revert "added error handling"

This reverts commit 69340980d2c84056a2bcf126ea77f4b5ed4cddf3.

* Revert "added WIP password change dialog with await"

This reverts commit 9e43113e07b10421b39575f6c7dd14287662b90d.

* added a fix to check

* added fixes

* added back in change password changes

* added in comment

* added suggested changes

* removed param colons

* Update extensions/mssql/src/errorDiagnostics/errorDiagnosticsProvider.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update src/sql/azdata.proposed.d.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* fixed conversion and provider dialog

* altered comments

* Update src/sql/platform/connection/common/utils.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* renamed Id

* Update src/sql/platform/connection/common/utils.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Improvements for Change password dialog + logs added (#21794)

* Improvements for Change password dialog + logs added

* Include server

* fixed tab space

* added comment

---------

Co-authored-by: Alex Ma <alma1@microsoft.com>

* Update src/sql/azdata.proposed.d.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* added fix to id to extHostErrorDiagnostics

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Lewis Sanchez <87730006+lewis-sanchez@users.noreply.github.com>
Co-authored-by: Alan Ren <alanren@microsoft.com>
Co-authored-by: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Co-authored-by: Cheena Malhotra <cmalhotra@microsoft.com>
Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-01-31 14:31:12 -08:00
AkshayMata
e1bbcb2ff1 Bump sql migration version to 1.2.4 (#21792)
Co-authored-by: Akshay Mata <akma@microsoft.com>
2023-01-31 10:20:30 -08:00
AkshayMata
fcece32cdd [SQL-Migration] Enable login migrations to SQL VM (#21776)
This PR adds support for migrating logins to SQL VM. Adding support for 2 scenarios supported here: VMs with private IP and public IP.
2023-01-31 09:47:16 -08:00
Alex Hsu
66bdc54c89 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230131164415383. (#21789) 2023-01-31 08:54:22 -08:00
Maddy
a38e8a74c3 fix file relative path issue on mac (#21438)
* use pathname vs nodeValue

* add test

* add comment

* only when editing in rich text

* refactor

* fix build errors

* fix hygiene errors

* remove fs check

* compare decodedUri to get correct relative paths

* Add Azure Resource 'Sql' to MSSQL extension. (#21600)

* [Loc] added sql.xlf schema (#21687)

* vbump profiler extension (#21685)

* Fix connect icon for Arc extension (#21659)

* Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230121171613142. (#21690)

* Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230122164538349. (#21693)

Co-authored-by: Alex Ma <alma1@microsoft.com>

* Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230123164122334. (#21697)

Co-authored-by: Alex Ma <alma1@microsoft.com>

* use normalize to get the path correctly

* add comment

* refactor

* more tests

* typo fix

---------

Co-authored-by: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Co-authored-by: Alex Ma <alma1@microsoft.com>
Co-authored-by: Alan Ren <alanren@microsoft.com>
Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
Co-authored-by: Alex Hsu <csigs@users.noreply.github.com>
2023-01-30 13:56:55 -08:00
Charles Gagnon
ad69164f09 Extension telemetry feature cleanup (#21779)
* Extension telemetry feature cleanup

* one more
2023-01-30 13:14:38 -08:00
Charles Gagnon
c33d2cc40a Bump ads-extension-telemetry to 1.3.4 (#21778) 2023-01-30 13:13:57 -08:00
Karl Burtram
0cba2f980d Update changelog for 1.41.1 (#21777)
* Update changelog for 1.41.1

* Fix typo

* Spelling error

* Fix issue areas
2023-01-30 11:24:19 -08:00
Alex Hsu
72651819d6 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230128164834584. (#21770) 2023-01-28 15:58:28 -08:00
Cheena Malhotra
f43afff8d1 Show tenant dropdown when selecting 'AzureMFA' for first time (#21763) 2023-01-27 16:08:11 -08:00
Charles Gagnon
e1e2227f2f Fix mispelled file name (#21762) 2023-01-27 15:42:16 -08:00
Charles Gagnon
d8c54ccd56 Add managed instance icon (#21742)
* Add managed instance icon

* Use const

* fix
2023-01-27 14:33:40 -08:00
Cheena Malhotra
1e0e792cef Update STS (#21761) 2023-01-27 14:24:40 -08:00
Kim Santiago
e7f9763237 fix undefined error in dacpac extension when sending telemetry (#21727)
* fix undefined error in dacpac extension when sending telemetry

* update interface
2023-01-27 13:22:16 -08:00
Charles Gagnon
08fb04f966 Update ads-service-downloader (#21754) 2023-01-27 12:12:04 -08:00
Cheena Malhotra
895b43f36a Fix account and tenant selection behavior (#21749) 2023-01-27 11:47:24 -08:00
Kim Santiago
b273cf5a65 fix update project from db dialog not choosing the db of the connection (#21746) 2023-01-27 10:17:31 -08:00
Alex Ma
75d455185a [Loc] changes to CMS and MSSQL xlfs (#21748) 2023-01-26 18:13:41 -08:00
Sakshi Sharma
655588891c Set current connection as the selected connection in schema compare dialog (#21682)
* Set current connection as the selected connection in schema compare dialog

* Address comment
2023-01-26 14:44:02 -08:00
Cheena Malhotra
f2f3d1c4ef Introduce 'Command Timeout' option for MSSQL connections (#21734) 2023-01-26 13:50:21 -08:00
Kim Santiago
cf5572a7f1 vbump dacpac, schema compare, and sql projects after Jan release (#21739) 2023-01-26 11:29:25 -08:00
Alan Ren
c11b50ff59 vbump profiler extension after release (#21740) 2023-01-26 11:25:51 -08:00
Alex Hsu
f22840c942 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230126164950302. (#21738) 2023-01-26 10:20:48 -08:00
Alex Ma
889ed3584e [Loc] updated xlfs for 1-25-2023 (#21733) 2023-01-25 18:11:19 -08:00
Cheena Malhotra
81b7cd2612 Introduce mssql connection property 'host name in certificate' (#21064) 2023-01-25 17:09:28 -08:00
Hai Cao
065dfef1e4 bump STS (#21730) 2023-01-25 14:56:28 -08:00
Candice Ye
5b3279065b Bumped versions up to 1.8.0 (#21725)
Co-authored-by: Candice Ye <canye@microsoft.com>
2023-01-25 13:38:34 -08:00
erpett
4a061da9da Post release Changelog/Readme updates (#21726) 2023-01-25 12:40:01 -08:00
Kim Santiago
17949b9d03 Initial support for SQLCMD variables in sql project tree (#21574)
* initial changes

* sqlcmd node showing in tree

* Add edit sqlcmdvar command

* remove commands on sqlcmd vars  for now

* cleanup

* fix tests

* add icons

* remove TestProject

* add checks for undefined

* add variable
2023-01-25 10:19:39 -08:00
Alex Hsu
a63f43088e Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230125165553635. (#21723) 2023-01-25 09:11:23 -08:00
junierch
5157508dd5 Junierch/mi tde (#21573)
* WIP

* wip tde wizard

* wip for merge w master

* wip

* wip share

* tde wizard

* PR reviews updates

* PR review updates

* PR updates

* PR review updates

* PR reviews updates

* Bump STS to 4.4.0.22

* PR reviews updates

* fix localize build issue

* fix build issue with localize

* remove unused function

* Windows only flag. Bug Bash fixes

* Use azdata with latest STS changes

* revert azdata, other PR comments

* sts and extesion version upgraded. logins back
2023-01-25 09:58:07 -05:00
Alex Ma
0e0fade5d8 [Loc] update to arc and sql xlfs (#21719) 2023-01-24 19:57:16 -08:00
Cheena Malhotra
84fd46c901 Do not show warning messages for stale accounts (#21621) 2023-01-24 16:21:43 -08:00
Cheena Malhotra
ef240a9a63 [Azure Arc] Update MIAA model to include encryption properties (#21702) 2023-01-24 16:20:35 -08:00
AkshayMata
427a859c63 Bump sql-migration version to 1.2.2 (#21717)
This PR bumps sql-migration version to 1.2.2 in order to release to insider's gallery. This also disables the LoginMigration button as we do not want to release it to public yet.
2023-01-24 15:13:18 -08:00
siyang yao
6631f8e2d9 ADS: Make select all tables by default instead of having to click edit and do select all (#21698)
* table are selected as default

* refactor

* fix save and close bug
2023-01-24 11:53:12 -08:00
Kim Santiago
c970887d5e cleanup sql project TestProject created by test (#21705) 2023-01-24 11:20:16 -08:00
Aasim Khan
ccc8df31c7 Adding prompt for delete connection (#21624)
* Adding prompt for disconnect

* changing to Idialog service

* Code cleanup and fixing comments

* Adding comments and making a test async

* removing then and awaiting for function
2023-01-23 22:56:09 -08:00
Alex Ma
ec4bc7f7db [Loc] update to sql migration xlf for 1-23-23 (#21713) 2023-01-23 18:15:13 -08:00
AkshayMata
58136f7c35 Bump sql-migration version to 1.2.1 (#21711)
Co-authored-by: Akshay Mata <akma@microsoft.com>
2023-01-23 17:11:25 -08:00
AkshayMata
03f6a9b188 [SQL-Migration] Login Migration Improvements (#21694)
This PR adds various login migration improvements:

- Enabled windows login by prompting user for AAD domain name if a windows login is selected
image
- Adds new login details dialog which gives granular status on each step of the login migration for each login
image
- Checks if windows login migration is supported for selected target type, and only collections source windows logins accordingly
- Perf optimization by source and target login in background of step 1 in order to significantly speed up loading of page 2
2023-01-23 15:29:44 -08:00
Raymond Truong
9d4d5374d7 [SQL Migration] Disable IR scenario and check page blobs for SQL VM <= 2014 (#21373)
* Disable IR scenario and add info box for source < 2014

* Update text and link

* Clean up

* Fix issue where switching to another target platform wouldn't clear restriction

* Remove locale from documentation URL

* Refactor

* Clean up

* Autoselect blob scenario

* Refactor

* Add page blog check

* Clean up

* Update UI logic
2023-01-23 14:20:06 -08:00
Raymond Truong
ac4aa8db9a [SQL Migration] Add info boxes for VM existing database names (#21566) 2023-01-23 13:45:59 -08:00
Alex Ma
205e683a4d Added localized vscode extensions to localization source files (#21684)
* added localized vscode extensions

* bump to 1.42
2023-01-23 12:42:31 -08:00
Karl Burtram
ac4afbec6c Add allow list of valid notebook command uris (#163322) (#21701)
* Add allow list of valid notebook command uris (#163322)

This restricts notebooks to run three command uris. These 3 commands should all be safe to run, even with untrusted inputs

* Fix incorrectly resolved merge conflict

Co-authored-by: Matt Bierner <matb@microsoft.com>
2023-01-23 12:01:53 -08:00
Karl Burtram
cabe158f07 Normalize resources when checking valid roots (#163327) (#21700)
Fix MSCR 74267

Fix https://github.com/microsoft/vscode-internalbacklog/issues/3140

Remove extra indexOf check

This could cause failures for files such as `img..png`

Co-authored-by: Matt Bierner <matb@microsoft.com>
2023-01-23 12:01:36 -08:00
Karl Burtram
ce0710a4b4 Safer construction of notebook html (#170987) (#21699)
Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>
2023-01-23 12:00:33 -08:00
Alex Hsu
9b25406dfb Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230123164122334. (#21697)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2023-01-23 10:05:31 -08:00
Alex Hsu
3e19c5769c Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230122164538349. (#21693)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2023-01-23 10:02:56 -08:00
Alex Hsu
9213325dc7 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230121171613142. (#21690) 2023-01-23 09:56:38 -08:00
Charles Gagnon
e2a7767b53 Fix connect icon for Arc extension (#21659) 2023-01-20 22:37:21 -08:00
Alan Ren
005b1ff35b vbump profiler extension (#21685) 2023-01-20 16:59:01 -08:00
Alex Ma
c36ae27e9b [Loc] added sql.xlf schema (#21687) 2023-01-20 16:35:50 -08:00
Cheena Malhotra
b3acef3124 Add Azure Resource 'Sql' to MSSQL extension. (#21600) 2023-01-20 13:08:38 -08:00
Aasim Khan
4971a94244 Fixing nvda (#21625) 2023-01-20 12:51:34 -08:00
Cory Rivera
ee1ec8e759 Build vertical actionbar before results table so that it shows above the table. (#21668) 2023-01-19 16:19:24 -08:00
Alex Ma
aeb833578d [Loc] update to sql and resource-deployment xlfs for 1-19-2023 (#21669) 2023-01-19 15:40:09 -08:00
Leila Lali
99f342e98c Updating ML version for next release (#21613) 2023-01-19 11:21:16 -08:00
Leila Lali
1fc12876cd Adding an owner for ML extension (#21614) 2023-01-19 11:08:40 -08:00
Alan Ren
6d2a5cbd60 remove preview text for sql 2022 (#21638) 2023-01-18 20:29:28 -08:00
Lewis Sanchez
f74d6f6d9b Copy Headers for Selected Columns (#21622)
* Adds copy header delimiter setting

* Copies all table headers or selected headers only

* Adds missing comments

* Update src/sql/workbench/contrib/query/browser/query.contribution.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update src/sql/workbench/contrib/query/browser/query.contribution.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Creates sort map entries function

* Removes CSV formatting and setting.

* Add colons before error message

* Renames table column sorting method

* Removes extra unnecessary function call

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-01-18 13:20:27 -08:00
Charles Gagnon
395daddbcd Bump scaleoutdataservice (#21628) 2023-01-18 10:56:54 -08:00
Alex Ma
097b92b94b Added a refresh of localization filters based on latest version of ADS (#21620) 2023-01-18 09:40:02 -08:00
Aasim Khan
3b31d1018f Adding better handling for checkbox column based row selection (#21553)
* Adding better handling for checkbox column based row selection

* Replacing any with proper typings
2023-01-18 01:20:26 -08:00
Charles Gagnon
85eb7b8824 Add trace debug logging to OE service (#21617)
* Add trace debug logging to OE service

* cleanup
2023-01-17 17:00:21 -08:00
erpett
a03c7b7a61 updating version number in main to 1.42 since we have forked the release branch (#21609) 2023-01-17 12:41:08 -08:00
dependabot[bot]
9f0a88587b Bump lodash from 4.17.11 to 4.17.21 in /extensions/datavirtualization (#21606)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.21)

---
updated-dependencies:
- dependency-name: lodash
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-17 11:42:55 -08:00
dependabot[bot]
036163ac79 Bump json5 from 2.2.0 to 2.2.3 in /extensions/datavirtualization (#21605)
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-17 11:42:44 -08:00
dependabot[bot]
c5ea8aefa3 Bump minimist from 1.2.5 to 1.2.7 in /extensions/datavirtualization (#21604)
Bumps [minimist](https://github.com/minimistjs/minimist) from 1.2.5 to 1.2.7.
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.7)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-17 11:42:37 -08:00
Charles Gagnon
60147c1a86 Fixes/cleanup for datavirtualization (#21608)
* Fixes/cleanup for datavirtualization

* Update owners
2023-01-17 11:42:26 -08:00
Alex Hsu
68cbff38f4 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230117164110186. (#21602) 2023-01-17 10:14:34 -08:00
Alex Hsu
63b0f1234d Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230116164552190. (#21599) 2023-01-17 10:14:10 -08:00
Charles Gagnon
ec838947b0 Add datavirtualization extension (#21594)
* initial

* cleanup

* Add typings ref

* fix compile

* remove unused

* add missing

* another unused

* Use newer vscodetestcover

* newer dataprotocol

* format

* cleanup ignores

* fix out path

* fix entry point

* more cleanup

* Move into src folder

* Handle service client log messages

* remove unused
2023-01-17 09:57:21 -08:00
Alex Ma
9184c414de [Loc] update to mssql xlf with tracing string (#21593) 2023-01-13 16:28:39 -08:00
Charles Gagnon
d51273d9cf Add config for enabling STS communication logging (#21591)
* Add config for enabling STS communication logging

* Add warning to description
2023-01-13 14:49:49 -08:00
junierch
ce5cb32084 tde-mi contracts (#21592)
* tde-mi contracts

* PR reviews updates
2023-01-13 17:41:40 -05:00
Alex Ma
30a2770228 Update to langpack source files for January release (#21351)
* update to langpack xlfs

* update to langpack source files

* added updated source files and dates

* Update for 12-19-2022

* Update for 12-21-2022

* update for 1/3/2023

* update to azurecore 1-9-2023

* last update to langpack source file before release
2023-01-13 14:01:35 -08:00
Alex Hsu
429bb3a877 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230113164226746. (#21589) 2023-01-13 10:08:18 -08:00
Cheena Malhotra
3239bb429f Null Check for errorNumber (#21586) 2023-01-12 18:27:10 -08:00
Raymond Truong
49c46cee20 Update contracts (#21577) 2023-01-12 18:23:23 -08:00
Alex Ma
d87a33188c [Loc] additional strings added to sql-migration (#21585) 2023-01-12 16:51:08 -08:00
Christopher Suh
90ef8e4907 Remove duplicate account entries (#21575) 2023-01-12 12:35:16 -08:00
Raymond Truong
0a93f1f3ef [SQL Migration] Implement state validation for SQL VM targets (#21350)
* WIP

* Implement POC

* Add strings

* Disable IR scenario and add info box for source < 2014

* Refactor

* Case insensitive string compare

* Remove unused strings
2023-01-12 11:39:32 -08:00
Alex Ma
9e13948b2b [Loc] update to sql-migration xlf (#21582) 2023-01-12 11:23:11 -08:00
junierch
5b9306ce83 bump STS 4.4.0.22 (#21581) 2023-01-12 13:18:10 -05:00
siyang yao
37f81d9ec2 [SQLDB-Migration] Collation Validation (#21572)
Adding collation validation in target database selection page.

collecting source database info including state, size, collation etc in the step 1 (select databases to assess and migrate)
comparing source database collation and target database collation in target selection page.
image
2023-01-12 09:45:02 -08:00
Alex Ma
52f9a476a0 [Loc] update to SQL xlf for 1-11-2023 (#21576) 2023-01-11 17:22:17 -08:00
Lewis Sanchez
7683259097 Add option to show and hide the action bar in the query results view (#21560)
* Show and hide action bar in results view

* Updates show action bar setting description

* Removes excess padding

* Code review change
2023-01-11 16:16:08 -08:00
Cheena Malhotra
9708b470c7 Azure core | Include alternate library accounts if found (#21565) 2023-01-11 16:05:20 -08:00
Lewis Sanchez
16740ba61f Adds functionality to copy table column headers (#21564)
* Adds functionality to copy table column headers

* Minor clean up

* Code review changes

* Removes unneeded comma
2023-01-11 09:17:05 -08:00
Lewis Sanchez
a400ff2f43 Save sql plan no longer uses the exact same name as the default (#21563)
* Save sql plan no longer uses the same name

* Minor clean up
2023-01-10 16:59:37 -08:00
Hai Cao
5a433fbd39 bump STS (#21561) 2023-01-10 12:08:25 -08:00
Cheena Malhotra
fd2ced449b Skip fetching access token when opening context menu in OE (#21557) 2023-01-09 21:22:02 -08:00
dependabot[bot]
dbd936d0d4 Bump json5 from 2.1.3 to 2.2.3 in /extensions/arc (#21544)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-09 10:07:10 -08:00
dependabot[bot]
306c328d02 Bump json5 from 2.1.3 to 2.2.3 in /extensions/azcli (#21543)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-09 10:05:27 -08:00
Cheena Malhotra
b9e8a87472 Fix resource endpoints to end with slash (#21540) 2023-01-06 17:53:09 -08:00
dependabot[bot]
c35dd95525 Bump json5 from 2.1.3 to 2.2.3 in /extensions/admin-tool-ext-win (#21546)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 17:23:39 -08:00
Lewis Sanchez
8c8a7859a0 Stops second invocation of createNewSession while expanding OE tree items on disconnected servers (#21437)
* Debounces second invocation while expanding OE tree items

* Minor clean up

* Adjusts debounce time

* Adding temp trace comments

* Adds missing semicolon

* Removes debouncer to stop 2nd newSession calls

* Removes temp trace comments

* Updates comment

Co-authored-by: Alan Ren <alanren@microsoft.com>
2023-01-06 16:10:19 -08:00
dependabot[bot]
ad006cdb63 Bump json5 from 2.1.3 to 2.2.3 in /extensions/machine-learning (#21514)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 16:03:27 -08:00
dependabot[bot]
31df835ab5 Bump json5 from 2.1.3 to 2.2.3 in /extensions/notebook (#21516)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 13:29:41 -08:00
dependabot[bot]
31f803e991 Bump json5 from 1.0.1 to 1.0.2 (#21548)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:37:03 -08:00
dependabot[bot]
1c257404c8 Bump json5 from 2.1.3 to 2.2.3 in /extensions/dacpac (#21535)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:36:48 -08:00
dependabot[bot]
64fbc17a52 Bump json5 from 2.1.3 to 2.2.3 in /extensions/data-workspace (#21531)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:36:23 -08:00
dependabot[bot]
d6ea817416 Bump json5 from 2.1.3 to 2.2.3 in /extensions/schema-compare (#21519)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:36:02 -08:00
dependabot[bot]
47c4353d9c Bump json5 from 2.2.1 to 2.2.3 in /build (#21547)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:33:01 -08:00
dependabot[bot]
c2bd712479 Bump json5 from 2.1.3 to 2.2.3 in /extensions/agent (#21545)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:30:58 -08:00
dependabot[bot]
0f3ff7f2d5 Bump json5 from 2.1.3 to 2.2.3 in /extensions/mssql (#21517)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:30:00 -08:00
dependabot[bot]
48baf6ab99 Bump json5 from 2.1.3 to 2.2.3 in /extensions/azurecore (#21542)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:29:31 -08:00
dependabot[bot]
47b2187c76 Bump json5 from 2.1.3 to 2.2.3 in /extensions/resource-deployment (#21512)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:28:55 -08:00
dependabot[bot]
bfb6ee914d Bump json5 from 2.1.3 to 2.2.3 in /extensions/integration-tests (#21518)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:28:06 -08:00
dependabot[bot]
ac5ce6f917 Bump json5 from 2.1.3 to 2.2.3 in /extensions/import (#21511)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:26:39 -08:00
dependabot[bot]
b018b42846 Bump json5 from 2.1.3 to 2.2.3 in /extensions/cms (#21539)
Bumps [json5](https://github.com/json5/json5) from 2.1.3 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.1.3...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 10:26:05 -08:00
Alex Hsu
449d9aa9e1 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230106164035861. (#21537)
Co-authored-by: Alex Ma <alma1@microsoft.com>
2023-01-06 09:39:37 -08:00
Alex Hsu
3a7059325c Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230105171657930. (#21528) 2023-01-06 09:37:45 -08:00
dependabot[bot]
3f030978d4 Bump json5 from 2.2.1 to 2.2.3 in /extensions/query-history (#21515)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-06 09:34:33 -08:00
dependabot[bot]
d2094934a4 Bump json5 from 2.2.0 to 2.2.3 in /extensions/sql-bindings (#21513)
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 22:49:39 -08:00
Alan Ren
88ab7947a4 fix issue caused by execution plan provider (#21533) 2023-01-05 21:12:49 -08:00
Cheena Malhotra
ec7e754009 Handle default tenant to be set when only 1 tenant exists (#21532) 2023-01-05 16:40:16 -08:00
dependabot[bot]
e904439060 Bump json5 from 2.2.0 to 2.2.3 in /extensions/sql-database-projects (#21510)
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 13:09:27 -08:00
Alan Ren
54d25210c4 new slickgrid version (#21524) 2023-01-05 07:14:35 -08:00
Cheena Malhotra
36484d38e6 Support locking cache file when writing and handles syntax error when reading (#21469) 2023-01-04 11:50:17 -08:00
Kim Santiago
5fbbc3a76b Change how data-workspace activates project extensions (#21470)
* change how data workspace activates project extensions

* cleanup

* undo whitespace change

* Update extensions/data-workspace/src/services/workspaceService.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* activate extensions on data workspace new and open commands

* Update extensions/data-workspace/src/services/workspaceService.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2023-01-04 11:47:51 -08:00
Alan Ren
a1803a823b handle the line breaks in link cells (#21504)
* handle the line breaks in link cells

* line break character
2023-01-04 10:23:01 -08:00
Cheena Malhotra
e7fcda7351 Filter accounts based on Auth library in accounts management service (#21501) 2023-01-03 20:16:08 -08:00
Charles Gagnon
29c88923f5 Fix Firewall Rule dialog dropdowns (#21499)
* Fix Firewall Rule dialog dropdowns

* Fix tenant dropdown
2023-01-03 16:24:59 -08:00
Josh Parnham
7d11b88b43 Change execution plan default save location when not in a workspace (#21461) 2023-01-03 14:51:30 -08:00
Alex Ma
af99e62385 [Loc] update to azurecore xlf for 1-3-2023 (#21496) 2023-01-03 11:10:26 -08:00
Sakshi Sharma
d86044c4e3 Add project dropdown to Update project from database dialog (#21446)
* Add dropdown populated with projects in current workspace in Update Project from database dialog for target project location

* Select first from the list if no project is preselected

* Address comments
2023-01-03 09:52:14 -08:00
Alex Hsu
687bd1854c Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20230102164143072. (#21492) 2023-01-03 09:08:40 -08:00
Karl Burtram
0930782236 Update changelog for Dec Hotfix 2 (#21484) 2022-12-27 09:59:45 -08:00
Charles Gagnon
228b4cb250 Update SQL grammar (#21481) 2022-12-23 17:51:44 -08:00
Cheena Malhotra
0ba0205ee8 Update jsonwebtoken@9.0.0 (#21474) 2022-12-22 21:32:01 -08:00
Cheena Malhotra
8032d50768 Introduce Azure Synapse Analytics and Dedicated SQL Pools azure nodes (#21471) 2022-12-22 17:41:11 -08:00
Vladimir Chernov
7b4f31d618 update STS for sql assessment version 1.1.17 (#1797) (#21473) 2022-12-22 17:40:27 -08:00
Lewis Sanchez
4a1e5001f0 Fixes object explorer's manage keybinding shortcut (#21459)
* Fixes object explorer's manage keybinding shortcut

* Update src/sql/workbench/contrib/dashboard/browser/dashboardActions.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update src/sql/workbench/contrib/dashboard/browser/dashboardActions.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update src/sql/workbench/contrib/dashboard/browser/dashboardActions.ts

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fixes OEManageConnectionAction ctor missing argument

* Updates no connection profile comment

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
2022-12-22 10:49:18 -08:00
Charles Gagnon
eb880834fb Update ads-extension-telemetry (#21468)
* Update ads-extension-telemetry

* undo
2022-12-22 09:26:54 -08:00
Hai Cao
29c8d4bd3d port fix for vscode issue 160827 (#21457) 2022-12-21 10:37:55 -08:00
Alex Hsu
6998c8787f Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221220164135572. (#21455) 2022-12-20 09:34:28 -08:00
Cheena Malhotra
87f1d14357 Reset expiresOn property for non-Azure connections (#21452) 2022-12-19 13:04:39 -08:00
Alex Hsu
fb121f2564 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221218164726369. (#21447) 2022-12-18 13:31:54 -08:00
Alex Ma
7a6da2dba7 [Loc] updates to sql-migration and sql (#21445) 2022-12-17 18:12:23 -08:00
AkshayMata
e223b4e870 Add new wizard for login migrations experience (#21317) 2022-12-17 12:11:25 -05:00
Cheena Malhotra
ff4dc9fe86 Update STS for firewall rule name (#21433) 2022-12-16 18:30:03 -08:00
Cheena Malhotra
ca22686061 Add support for firewall rule name (#21430) 2022-12-16 18:29:44 -08:00
Alex Ma
e2b1e6cbf3 [Loc] update to sql-database-projects and sql-migration xlfs (#21440) 2022-12-16 18:11:30 -08:00
brian-harris
2e240729af Add IR Migration configuration Validation to SQL Migration extension (#21386)
* re-factor and consolidate wizard pages

* validation WIP 11/10

* validate ir dialog

* navigation fixes

* bump version to 1.2.0

* add resource strings and fix navigatin issue

* map validation state to resource string clean up

* address review comments

* fix typos, address review comments

* address review feedback, readability

* fix res string, validation check, col width

* bug fixes, nav, sqldb migration

* fix nav/refresh/visibility issues

* fix nav issues, cancel pending validation items

* update error text / position

* fix localization bug
2022-12-16 14:52:24 -08:00
Kim Santiago
754d70d654 Add validation for checking for dacpac being on the same drive (#21434)
* add extra validation for add dacpac reference quickpick

* Add placeholder with message
2022-12-16 14:18:26 -08:00
Alex Ma
710fb0df62 [Loc] remove cacheErrorRemove (#21436) 2022-12-16 14:12:43 -08:00
Alan Ren
f91e40f2b9 new STS version (#21432) 2022-12-16 09:20:52 -08:00
Cheena Malhotra
112de46723 Fix ADAL to MSAL transition of connections and account list (#21425) 2022-12-15 16:38:45 -08:00
Alan Ren
a5e2e77042 auto resize column update (#21426) 2022-12-15 15:16:12 -08:00
Alan Ren
3aab4fd115 fix regex perf issue (#21421) 2022-12-15 10:43:17 -08:00
Kim Santiago
a4db7309af Fix schema compare not always showing diff color highlighting (#21413)
* Fix schema compare not always showing diff color highlighting

* move helper functions into diffEditorWidget.ts
2022-12-14 17:24:10 -08:00
Cheena Malhotra
234c3debaa Fix issues when setting azureTenantId (#21412) 2022-12-14 12:03:11 -08:00
Alex Ma
0638bbb152 Bump MSSQL for password change feature (#21417)
* added bumps

* added correct STS

* added updated yarn

* bump STS version
2022-12-14 10:52:41 -08:00
Sakshi Sharma
d0861f01ed Update string to enum for folder structure (#21406)
* Update string to enum

* Remove newly added enum value
2022-12-14 08:43:17 -08:00
Alex Hsu
bc8d4d2f48 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221213164123560. (#21410) 2022-12-13 09:12:10 -08:00
Aasim Khan
ed43817da7 Revert "Auto closing issues that needs logs after 7 days of inactivity. (#21390)" (#21403)
This reverts commit 30f4a3554a.
2022-12-12 13:45:46 -08:00
Hai Cao
6254e2af81 bump STS (#21402) 2022-12-12 13:16:07 -08:00
Aasim Khan
30f4a3554a Auto closing issues that needs logs after 7 days of inactivity. (#21390)
* Adding old issue

* Adding needs more info

* Making a different step for every issue label
2022-12-12 12:31:47 -08:00
Cheena Malhotra
abc7ada902 Fallback to 'common' tenant if 'tid' not found (#21388) 2022-12-12 12:31:14 -08:00
Sakshi Sharma
2626f24d5a Remove fs.promises.rmdir (#21356)
* Remove fs.promises.rmdir

* Add force flag
2022-12-12 11:04:31 -08:00
Cory Rivera
c1e97cd9ff Check current notebook cell when refreshing intellisense cache (#21394) 2022-12-12 10:50:54 -08:00
Kim Santiago
146d64435a fix dacpac wizard not using correct connection (#21387) 2022-12-12 10:14:08 -08:00
Alan Ren
6cfa0910b6 fix h-scrollbar cutoff issue (#21396) 2022-12-12 09:39:33 -08:00
Alex Hsu
5a6db7def1 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221211164417851. (#21400) 2022-12-11 21:46:00 -08:00
Alex Hsu
a4ee4440cc Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221210164542912. (#21399) 2022-12-10 12:30:42 -08:00
Alex Ma
85f29cb988 [Loc] added refactored import.xlf (#21397) 2022-12-09 16:59:30 -08:00
Aasim Khan
7bc8aa8d1f updating data client protocol in import extension (#21391) 2022-12-09 16:10:29 -08:00
Alex Ma
abc98224fa [Loc] Added status query summary text (#21395) 2022-12-09 15:49:37 -08:00
Alan Ren
8d3b7ee205 enhance the selection summary (#21392)
* enhance the selection summary

* update comment
2022-12-09 14:07:47 -08:00
Alan Ren
17b41ae3d7 fix link cell style issue (#21389) 2022-12-08 21:53:52 -08:00
Aasim Khan
d0b2dc702f Updating out of scope comment (#21384) 2022-12-08 16:38:40 -08:00
Alex Ma
60add80fb0 [Loc] sql xlf update, add not supported kernal message (#21385) 2022-12-08 14:49:02 -08:00
Cory Rivera
272e748424 Show a message if kernel is not supported when first opening a notebook. (#21376) 2022-12-08 10:27:57 -08:00
Alex Hsu
286d195b22 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221208163933102. (#21382) 2022-12-08 09:55:18 -08:00
Alex Ma
fb6e221fff [Loc] added small change to password change dialog localization (#21377) 2022-12-07 15:03:45 -08:00
Alex Ma
cffba368a9 Added reset password dialog upon SQL Server expired password error (#21295)
* Added initial password connection dialog box

* made small changes

* more preliminary work

* more WIP changes

* more cleanup done

* added dialog instantiation

* added placeholder dialog window

* added changePasswordController

* made some changes to changePasswordController

* some changes made

* added more changes

* more changes made to dialogue

* added password confirm box

* added WIP change password function

* small changes made to API

* small changes for test

* added  uri

* added valid password

* added TODO comments

* added small change to connectionManagementService

* added connectionManagementService password change

* added comment on what to do next

* made some simplification of change password

* added response callback

* added fixes to protocol

* added throw error for passwordChangeResult

* WIP added call to self after password change

* WIP changes to implementing new password change dialog

* added changes to passwordChangeDialog

* added launchChangePasswordDialog

* remove erroneous css

* added working dialog

* removed old password change dialog

* fixed space

* added checkbox option to passwordChangeDialog

* added test signatures

* added error handling

* added some changes

* added changes to HTML for passwordChangeDialog

* added CSS to passwordChangeDialog

* added display none for matching passwords

* added documentation changes

* small cleanup

* added working error catch and retry

* added await

* added recovery instructions

* Added ok button hide for button click.

* added loading spinner

* fixed for semicolon

* added updated message

* Added message change

* added minor fixes

* added small fixes

* made more changes

* renamed messages to errorDetails

* added styling to passwordChangeDialog

* simplified error message

* changed comment

* modified azdata to be consistent

* small changes

* change to azdata for consistency

* added clarification for provider

* removed additional instructions

* Added new dialog title

* addressed feedback

* added comments

* added changes
2022-12-07 14:27:01 -08:00
Alex Ma
db329049ff [Loc] updates to xlfs after removal of BDC (#21375) 2022-12-07 14:21:40 -08:00
Cory Rivera
e2327c393a Remove all Big Data Cluster features (#21369) 2022-12-07 12:28:17 -08:00
Alan Ren
bb1f5bfffe select cell after keyboard navigation (#21366)
* sync selected cell and active cell

* more packages
2022-12-06 08:53:42 -08:00
Karl Burtram
05eb8dd448 Add PowerBI PPE URI to domain list (#21357) 2022-12-05 15:03:01 -08:00
Alan Ren
5410e06cd7 remove extension (#21364) 2022-12-05 10:07:40 -08:00
Alan Ren
3b59fb825f add mysql to recommended extension list (#21362)
* add mysql to recommended list

* fix casing
2022-12-05 09:58:06 -08:00
Cheena Malhotra
e89341f6bd Set both label and values to custom options select Boxes (#21354) 2022-12-02 13:48:23 -08:00
Christopher Suh
b5d2debebb make MSAL default auth library (#21355) 2022-12-02 11:47:06 -08:00
Aasim Khan
1117a72ade Updating decode URI lib (#21349) 2022-12-01 22:13:45 -08:00
Cheena Malhotra
511523d002 Introduce inbuilt MsalCachePlugin to replace msal-node-extensions (#21335) 2022-11-30 21:23:32 -08:00
Cheena Malhotra
02e9f8d3ef Rename to security token to match STS (#21338) 2022-11-30 15:02:08 -08:00
Aasim Khan
945a134018 Vbumping electorn (#21336) 2022-11-30 12:19:12 -08:00
Aasim Khan
c0a194df4a Adding wizard and dialog footer loading spinner (#21230)
* Adding wizard and dialog loading

* Moving apis to proposed

* fixing namespace

* Only firing event when the value changes

* Only firing when value is changed

* Adding loading complete message to dialog and wizard

* Registering listeners and making a new base interface for loading components

* Fixing api comment

* Renaming prop to loadingCompleted

* old loading icon
2022-11-30 12:18:34 -08:00
Charles Gagnon
62d5c1f2d6 Fix action dropdowns focusing hidden button & fix ext action button (#21326) 2022-11-29 22:41:48 -08:00
Cheena Malhotra
23dfd690a6 Refresh token with SqlToolService session update (#21308) 2022-11-29 15:26:15 -08:00
Cheena Malhotra
0479aab107 Update STS to v4.4.0.8 (#21319) 2022-11-29 15:25:32 -08:00
Aasim Khan
813fa6b2ef Updating qs lib across ads (#21323) 2022-11-29 11:40:22 -08:00
Cory Rivera
4dfedabbc6 Dispose underlying text input in notebook input to clear editor service references correctly. (#21318) 2022-11-29 10:06:52 -08:00
Cheena Malhotra
be036ee215 Skip signing node_modules (#21311) 2022-11-28 16:20:58 -08:00
Maddy
815310f52a check for file protocol of vscode-file (#21302)
* check for file protocol vscode-file:

* use vscode constants
2022-11-28 15:19:02 -08:00
Alex Hsu
0e36a35caa Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221127163748785. (#21312) 2022-11-28 10:04:23 -08:00
Alex Hsu
2c86daa040 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221125170229478. (#21310) 2022-11-28 10:03:46 -08:00
Alex Hsu
3912844aaa Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221124163813636. (#21307) 2022-11-28 10:03:29 -08:00
Alex Ma
5275cc5ca0 [Loc] update to azurecore xlf (#21303) 2022-11-24 00:08:40 -08:00
Cheena Malhotra
405b3bbfdb Fix default auth and 'AzureTenantId' to persist and not reset on selection event (#21289) 2022-11-23 17:39:03 -08:00
Christopher Suh
86c3f315f2 Add MSAL Authentication Library support (#21024) 2022-11-23 14:06:44 -08:00
Charles Gagnon
fba47815e2 Cleanup changelog (#21300)
* Cleanup changelog

* fix

* Correct header

* fix indent

* fix other indent
2022-11-23 11:26:43 -08:00
Alex Hsu
a0dcb0c4af Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221123173210096. (#21298) 2022-11-23 09:51:40 -08:00
Charles Gagnon
8d13d4054a Update changelog for 1.40.1 release (#21297) 2022-11-23 09:29:17 -08:00
Cheena Malhotra
62b123624d Fix icon foreground (#21287) 2022-11-22 18:03:51 -08:00
Charles Gagnon
c9febe330c Bump STS to 4.4.0.7 (#21293) 2022-11-22 11:39:25 -08:00
Cheena Malhotra
3b6ce47acc Fix access token refresh design (ADS only) (#21206) 2022-11-21 19:35:00 -08:00
Alex Ma
8db40ab55f [Loc] update to sql-database-projects xlf (#21288) 2022-11-21 16:41:39 -08:00
Kim Santiago
3932332694 update sql projects strings to install .net 6 SDK instead of .net core 3.1 (#21235)
* update sql projects strings to install .net 6 SDK instead of .net core 3.1

* update to us aka.ms link
2022-11-21 11:53:12 -08:00
Kim Santiago
46aec180e2 hide generate sql project from OpenApi under preview configuration in vscode (#21263) 2022-11-21 11:06:24 -08:00
Sakshi Sharma
e79ec552e6 Sql projects: Tests for Create project from database for vscode extension (#21257)
* Test changes

* Tests for CreateProjectFromDatabaseQuickpick

* Address comments

* Update pwd to placeholder
2022-11-21 11:04:46 -08:00
Kim Santiago
ff56398fa9 add missing .dll in list of dlls used for project build (#21277) 2022-11-21 10:14:25 -08:00
Alex Hsu
1efc86768a Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221121163735365. (#21285) 2022-11-21 09:26:20 -08:00
Alex Hsu
47e2504484 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221120164123198. (#21283) 2022-11-21 09:26:02 -08:00
Alex Hsu
22d46668f4 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221119163941295. (#21278) 2022-11-21 09:25:46 -08:00
Cheena Malhotra
dec3c020c5 Fix Browse azure tab not populating right tenant (#21276) 2022-11-19 00:49:56 -08:00
Christopher Suh
0bc5f68d29 Fix prompt for auth/device auth method (#21272) 2022-11-18 15:17:46 -08:00
Cory Rivera
728a90cd53 Move New Notebook command to core (#21247) 2022-11-18 14:54:58 -08:00
Alan Ren
78b17bba82 vbump extensions after publish (#21275) 2022-11-18 14:17:24 -08:00
Alex Ma
18f090b8c2 [Loc] update to sql-database-projects (#21270) 2022-11-18 10:28:18 -08:00
Alex Hsu
8df2517a24 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221118164216506. (#21268) 2022-11-18 09:37:28 -08:00
Karl Burtram
236ba22053 Remove swiftshader dir from signing list (#21258) 2022-11-18 07:37:59 -08:00
Raymond Truong
0d62fa0224 Remove extra params (#21262) 2022-11-17 16:31:05 -08:00
Kim Santiago
ac494955ac Hide publish sql project to new azure server behind preview setting (#21248)
* hide publish to new Azure server under preview setting

* try adding additional properties instead of replacing everything in configuration

* cleanup and change to adding configuration properties instead of replacing the whole thing

* add more info in comment

* remove extra line
2022-11-17 16:05:46 -08:00
Raymond Truong
a238d15da2 [SQL Migration] Merge Nov extension release (1.1.3) changes to main (#21184)
* Vbump and update dependent ADS version (#21179)

* [SQL Migration] Add new Azure Core API changes back in to support USGov + other non-public clouds (#20476)

* WIP - show error message for failed SKU recommendation

* WIP - run query to get correct instance name

* WIP - integrate elastic model recommendation

* Remove private endpoint restriction text

* Add feature switch for elastic recommendation

* Clean up

* Clean up

* Misc UI fixes

* Update package.json with updated azdata dependency

* Remove unused lines

* Fix broken next button

* Vbump extension to 1.0.6

* Revert "[SQL Migration] Revert dependency on new Azure Core API changes (#20469)"

This reverts commit b7a633be25.

* [SQL Migration] Add additional condition for cutover  (#21178)

* Add new cutover condition

* Implement helper hasRestoreBlockingReason()
2022-11-17 14:13:08 -08:00
Kim Santiago
17d3489778 Update Microsoft.Build.Sql version to 0.1.7-preview (#21242)
* update the default Microsoft.Build.Sql version used by sql projects

* update Microsoft.Build.Sql SDK version

* update baselines and template to also use 0.1.7-preview
2022-11-17 14:09:03 -08:00
Alex Ma
6e54d3fecf [Loc] changes for 11/16/2022 (#21251) 2022-11-16 23:27:58 -08:00
Karl Burtram
ff32470ab0 Bump to Electron 19.1.6 (#21249) 2022-11-16 19:23:44 -08:00
dependabot[bot]
404d053050 Bump loader-utils from 1.4.1 to 1.4.2 (#21238)
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-16 13:52:15 -08:00
Karl Burtram
6b9d5db145 Update Electron to 19.1.3 (#21244)
* chore: bump electron@18.0.0-beta.4

* Merge commit

* chore: update electron@19.0.17 (#161027)

* chore: update electron@19.0.17

* chore: update API typings

* fix: compilation errors

* build: add libcups dependency

* chore: update electron@19.1.3 (#164864)

* Update yarn

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-11-16 13:52:02 -08:00
Kim Santiago
f977fe6cf6 vbump dacpac, schema compare, and sql projects after Nov release (#21241) 2022-11-16 13:32:05 -08:00
Alan Ren
bbcfd00967 post release extension vbump (#21243)
* Update package.json

* Update package.json
2022-11-16 11:43:53 -08:00
Kim Santiago
b4aed82d44 update working for dotnet install location setting (#21232) 2022-11-16 11:05:30 -08:00
Charles Gagnon
12bca68a0d Fix lint error in typings (#21240) 2022-11-16 10:05:36 -08:00
Karl Burtram
388a81e65b Typo in readme (#21239) 2022-11-16 09:20:27 -08:00
dependabot[bot]
f56aa9977c Bump minimatch from 3.0.4 to 3.1.2 in /build/npm/gyp (#21219)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-16 09:08:00 -08:00
dependabot[bot]
c79694fb3a Bump minimatch from 3.0.4 to 3.1.2 in /test/integration/browser (#21218)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-16 09:07:00 -08:00
erpett
803e5caa78 Updates for 1.40 readme and changelog (#21233)
* Updates for 1.40 readme and changelog

* update download table

Co-authored-by: Alan Ren <alanren@microsoft.com>
2022-11-16 08:59:59 -08:00
dependabot[bot]
8db6c0393a Bump minimatch from 3.0.4 to 3.1.2 in /test/automation (#21217)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-16 08:54:53 -08:00
Cory Rivera
a37d6230f9 Remove API compatibility layer for VS Code notebook extensions (#21225) 2022-11-15 10:38:41 -08:00
Alex Ma
1105e4d15c updates langpack source files to match 1.67 release (#21228)
* updates langpack source files to match 1.67 release

* added small version bump
2022-11-15 10:19:38 -08:00
Christopher Suh
c1e90092a8 add instructions to close Developer Tools (#21227) 2022-11-14 16:25:02 -08:00
Alex Hsu
89586aad0b Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221113165604395. (#21221) 2022-11-14 09:09:45 -08:00
Alan Ren
fa8d3bf0cf run tests for windows on arm build (#21214) 2022-11-11 23:49:38 -08:00
Alex Hsu
66dc7deca3 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221111164026766. (#21213) 2022-11-11 09:12:40 -08:00
Alan Ren
0a48fcbfaa add native arm64 builds for Windows (#21196) 2022-11-10 23:13:18 -08:00
Alex Ma
d5246092a5 [Loc] small update to sql-database-projects.xlf (#21203) 2022-11-10 16:49:24 -08:00
Aasim Khan
c8a80a5270 Adding SQL Carbon edit comment (#21202) 2022-11-10 15:46:05 -08:00
Lucy Zhang
7ca4e2bcae Fix headers being exported twice from notebooks (#21195)
* fix headers being exported twice

* simplify

* fix test
2022-11-10 13:31:36 -08:00
Kim Santiago
2a933d43c4 add preview for publish to Azure development container (#21199) 2022-11-10 13:25:54 -08:00
Cory Rivera
667f125cbd Bring back old editor resolving logic to fix saving in notebooks. (#21186) 2022-11-10 12:53:53 -08:00
Kim Santiago
e928ed660f projectController.ts code cleanup (#21112)
* adding regions and doc comments in projectController.ts

* cleanup

* add param info to doc comment
2022-11-10 11:59:04 -08:00
Hai Cao
9f8a50d311 bump STS (#21197) 2022-11-10 11:31:12 -08:00
Cheena Malhotra
be95e95989 Select available tenant Id instead of first one as default (#21190) 2022-11-10 11:24:27 -08:00
Cheena Malhotra
c5dbbecc34 Fix GitHub workflow (#21191) 2022-11-10 10:49:59 -08:00
Alex Hsu
a3bacceb87 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221110163839470. (#21194) 2022-11-10 09:15:24 -08:00
Kim Santiago
00f17bc050 put Generate project from OpenApi/Swagger spec behind preview flag (#21108) 2022-11-09 16:37:41 -08:00
Cheena Malhotra
3922117771 Fix custom option support in CMS + update providername in provided profile (#21183) 2022-11-09 15:50:25 -08:00
Aasim Khan
298cc4676b Updating id generation logic to avoid substring overlaps (#21181) 2022-11-09 15:40:20 -08:00
Alan Ren
d65ba42334 vbump cms (#21176) 2022-11-09 10:45:22 -08:00
Alex Ma
480c3d8779 [Loc] small change to sql.xlf (#21175) 2022-11-09 10:22:31 -08:00
Alex Hsu
3224b23f0f Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221109163936392. (#21173) 2022-11-09 08:58:47 -08:00
Karl Burtram
25d4d42d3e Fix casing on execution plan command titles (#21170) 2022-11-08 19:22:13 -08:00
dependabot[bot]
dc0d8f2357 Bump loader-utils from 1.4.0 to 1.4.1 (#21141)
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-08 12:47:20 -08:00
Kim Santiago
64f5d9dde3 remove edge template from sql projects new project dialog (#21144) 2022-11-08 11:13:21 -08:00
Karl Burtram
a374046638 Port VS Code issue 149177 (#21153) 2022-11-08 10:31:04 -08:00
Alex Hsu
1e8c289869 Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221108163801434. (#21154) 2022-11-08 09:06:36 -08:00
Alex Ma
2f3cc4f9b6 [Loc] small addition to sql.xlf (#21150) 2022-11-07 17:00:43 -08:00
Karl Burtram
80c3d3570e Remove LiveShare extension (#21143)
* Remove LiveShare extension

* Update build JS file
2022-11-07 16:27:03 -08:00
Alex Ma
aebceb8c16 Langpack source files update for November release (main branch PR) (#21147)
* updated localized XLFS

* update to langpack source files
2022-11-07 16:23:29 -08:00
erpett
87574053e0 vbump post release branch split (#21139) 2022-11-07 14:26:23 -08:00
Alex Hsu
0881f2b3fc Juno: check in to lego/hb_04604851-bac4-4681-9f74-73de611d6e48_20221107163900168. (#21128) 2022-11-07 13:35:19 -08:00
1474 changed files with 119504 additions and 139477 deletions

View File

@@ -24,8 +24,6 @@
**/node_modules/**
**/extensions/**/out/**
**/extensions/**/build/**
/extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts
/extensions/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts
**/extensions/**/colorize-fixtures/**
**/extensions/html-language-features/server/lib/jquery.d.ts
/extensions/markdown-language-features/media/**

View File

@@ -770,7 +770,6 @@
"chart.js",
"plotly.js",
"angular2-grid",
"kburtram-query-plan",
"html-to-image",
"turndown",
"gridstack",
@@ -1147,7 +1146,6 @@
"extensions/azuremonitor/src/prompts/**",
"extensions/azuremonitor/src/typings/findRemove.d.ts",
"extensions/kusto/src/prompts/**",
"extensions/mssql/src/hdfs/webhdfs.ts",
"extensions/mssql/src/prompts/**",
"extensions/mssql/src/typings/bufferStreamReader.d.ts",
"extensions/mssql/src/typings/findRemove.d.ts",

5
.github/CODEOWNERS vendored
View File

@@ -6,14 +6,17 @@
/extensions/arc/ @Charles-Gagnon @swells @candiceye
/extensions/azcli/ @Charles-Gagnon @swells @candiceye
/extensions/azurecore/ @cssuh @cheenamalhotra
/extensions/big-data-cluster/ @Charles-Gagnon
/extensions/dacpac/ @kisantia
/extensions/datavirtualization @Charles-Gagnon
/extensions/import @aasimkhan30
/extensions/machine-learning @llali
/extensions/notebook @azure-data-studio-notebook-devs
/extensions/query-history/ @Charles-Gagnon
/extensions/resource-deployment/ @Charles-Gagnon
/extensions/schema-compare/ @kisantia
/extensions/sql-bindings/ @vasubhog @Charles-Gagnon @lucyzhang929 @chlafreniere @MaddyDev
/extensions/sql-database-projects/ @Benjin @kisantia
/extensions/sql-migration @AkshayMata @raymondtruong @brian-harris @junierch @siyangMicrosoft
/extensions/mssql/config.json @Charles-Gagnon @alanrenmsft @kburtram
/src/sql/*.d.ts @alanrenmsft @Charles-Gagnon

View File

@@ -18,6 +18,7 @@ Next there are two types of logs to collect:
- Save this text into a file named console.log and attach it to this issue.
- Developer Tools can be closed via Help -> Toggle Developer Tools
**Application Logs**
@@ -46,8 +47,5 @@ Needs Logs - Azure:
# actions for Out of Scope label
Out of Scope:
comment: "Thank you for opening this suggestion! This enhancement is not planned in our
medium-term roadmap. The issue is being closed to reduce active issues to focus on
enhancements that are being considered for an upcoming release. We will review closed issues
with the 'Out of Scope' label when doing long-term planning."
comment: "Thank you for your feedback! This feature is currently out of scope and we do not plan to work on it in a currently planned release. We will close this issue to keep our backlog focused on requests that we are planning to work on. Please note that users can continue to vote and comment on closed issues, which we encourage as it helps us understand user interest and can provide more details about why a feature is requested."
close: true

View File

@@ -142,16 +142,9 @@ jobs:
id: electron-unit-tests
run: DISPLAY=:10 ./scripts/test.sh --runGlob "**/sql/**/*.test.js" --coverage
- name: Run Extension Unit Tests (Continue on Error) # {{SQL CARBON EDIT}} Run extension unit tests (continue on error)
id: electron-extension-unit-tests-continue-on-error
- name: Run Extension Unit Tests # {{SQL CARBON EDIT}} Rename to extension for clarity
id: electron-extension-unit-tests
run: DISPLAY=:10 ./scripts/test-extensions-unit.sh
continueOnError: true
condition: and(succeeded(), eq(variables['EXTENSION_UNIT_TESTS_FAIL_ON_ERROR'], 'false'))
- name: Run Extension Unit Tests (Fail on Error) # {{SQL CARBON EDIT}} Run extension unit tests (fail on error)
id: electron-extension-unit-tests-fail-on-error
run: DISPLAY=:10 ./scripts/test-extensions-unit.sh
condition: and(succeeded(), ne(variables['EXTENSION_UNIT_TESTS_FAIL_ON_ERROR'], 'false'))
# {{SQL CARBON EDIT}} Add coveralls. We merge first to get around issue where parallel builds weren't being combined correctly
- name: Combine code coverage files

View File

@@ -1,4 +1,4 @@
disturl "https://electronjs.org/headers"
target "17.4.11"
target "19.1.8"
runtime "electron"
build_from_source "true"

View File

@@ -1,11 +1,100 @@
# Change Log
## Version 1.41.2
* Release date: February 10, 2023
* Release status: General Availability
### Bug fixes in 1.41.2
| New Item | Details |
| --- | --- |
| Connection | Fixed a regression blocking connections to sovereign Azure clouds |
| Query Editor | Fixed a regression causing the Output window to display on each query execution |
## Version 1.41.1
* Release date: January 30, 2023
* Release status: General Availability
### Bug fixes in 1.41.1
| New Item | Details |
| --- | --- |
| Connection | Fixed a bug causing incorrect Azure account tenant selection when connecting to server through Azure view |
| Object Explorer | Fixed a regression causing Object Explorer to not show database objects for Azure SQL DB Basic SLO |
## Version 1.41.0
* Release date: January 25, 2023
* Release status: General Availability
### What's new in 1.41.0
| New Item | Details |
| --- | --- |
| Azure Subscriptions | Introduced Azure Synapse Analytics and Dedicated SQL Pools nodes. |
| Azure SQL Migration Extension | Premium series memory optimized SQL MI SKUs included in recommendations. |
| Connection | Migrated Azure authentication library from ADAL to MSAL. MSAL is the library used by default starting with release 1.41.  However, if you encounter issues, you can change back to ADAL within **Settings > Azure: Authentication Library**. |
| Connection | Added ability to provide a description when creating a firewall rule from Azure Data Studio. |
| Connection | Include ability to change password for new or expired login. |
| Connection | Add support for SQL Server Alias use when connecting to a server. |
| MongoDB Atlas Extension | Provides the ability to connect to and query data on MongoDB Atlas (Preview). |
| Notebooks | Provide option for users to convert markdown to a table or not when HMTL table tag is present. |
| Object Explorer | Databases are no longer brought online in serverless Azure SQL when Databases node is expanded. |
| Object Explorer | Added support for Ledger views. |
| Object Explorer | Fixed issue with key binding for objectExplorer.manage not working. |
| Query Editor | Fixes and updates to SQL grammar (colorization and auto-complete). |
| Query Plan Viewer | Changed default folder to be users home directory when saving a query plan. |
| Query Results | Added ability to only copy Column Headers, and only for cells that are highlighted. |
| Query Results | Added option to show or hide the action bar in the results window. |
| Query Results | Increased height of horizontal scrollbar in results window. |
| Query Results | Added new aggregate details in the results toolbar when selecting multiple cells. |
| SQL Projects Extension | Provide the ability select an existing project via a new dropdown. |
### Bug fixes in 1.41.0
| New Item | Details |
| --- | --- |
| Accessibility | Accessibility improvements were made in the Query Plan Viewer, Query History Extension and Migration Extension. |
| Big Data Cluster | Fix missing connect icon in BDC view header bar. |
| Big Data Cluster | Fixed issue preventing HDFS nodes for BDC servers in Object Explorer from expanding. |
| Connection | Added ability to delete a connection that has expired AAD credentials. |
| Connection | Improved experience when Azure Active Directory token expiration occurs. |
| Connection | Improved connection experience when using multiple Azure tenants. |
| Connection | Addressed problem with adding a firewall exception for a non-default Azure subscription. |
| Migration Extension | Added support for non-public clouds for migration scenarios. |
| MySQL Extension | Updated resource endpoints to support AAD logins in the MySQL extension. |
| Notebooks | Improve Intellisense refresh in Notebook cells. |
| Notebooks | Address issue with "New Notebook Job" resulting in an empty form. |
| Object Explorer | Fixed issue with database list not loading. |
| Query Execution | Fixed error generated when executing a query with LEFT JOIN and NULL values. |
| Query Plan Viewer | When saving query plans (.sqlplan file), the filename will numerically increment to prevent duplicate filenames. |
| Query Results | Fixed issue where users were unable to open JSON data as a new file. |
| Query Results | Provide proper cell selection and navigation in the query results grid. |
| Query Results | Improved the handling of line breaks when copying cell contents. |
| Query Results | Addressed issue where a column would re-size incorrectly when auto-sizing in the results output. |
| Query Results | Improved JSON cell handling from query results. |
| Query Results | Fixed behavior where focus was incorrectly set on a cell using keyboard navigation. |
| Resource Deployment | Remove 'Preview' flag for SQL Server 2022 deployment types. |
| Schema Compare Extension | Fixed problem where differences in schema compare were not being highlighted. |
| Schema Compare Extension | Permissions are now included in schema compare when the "Include Permissions" option is selected. |
| SQL Projects Extension | Changes to db_datawriter or db_datareader roles are now supported. |
| SQL Projects Extension | Updated Database Projects Net Core SDK Location dialog to be more descriptive. |
| Table Designer | Updated Table Designer to disable transaction support for Azure Synapse databases. |
| Table Designer | Addressed problem of the table name not refreshing after being updated prior to publishing. |
| Table Designer | Fixed issue where table designer could not be opened for existing Ledger tables. |
## Version 1.40.2
* Release date: December 27, 2022
* Release status: General Availability
### Bug fixes in 1.40.2
* Fix potential elevation of privilege issue using Bash shell on Windows. VS Code issue [#160827](https://github.com/microsoft/vscode/issues/160827)
## Version 1.40.1
* Release date: November 22, 2022
* Release status: General Availability
### Bug fixes in 1.40.1
* Fixed bug that caused folders in the servers tree to display incorrect contents [#21245](https://github.com/microsoft/azuredatastudio/issues/21245)
* Fixed bug that caused folders in the servers tree to display incorrect contents [#21245](https://github.com/microsoft/azuredatastudio/issues/21245)
## Version 1.40.0
* Release date: November 16, 2022
@@ -58,14 +147,14 @@
## Version 1.39.1
* Release date: August 30, 2022
* Release status: General Availability
## What's new in 1.39.1
* Bug fixes in 1.39.1
* Fixed bug that caused Database Trees in server connections to not expand in the Object Explorer.
### Bug fixes in 1.39.1
* Fixed bug that caused Database Trees in server connections to not expand in the Object Explorer.
## Version 1.39.0
* Release date: August 24, 2022
* Release status: General Availability
## What's new in 1.39.0
### What's new in 1.39.0
* New Features:
* Deployment Wizard - Azure Data Studio now supports SQL Server 2022 (Preview) in the Deployment Wizard for both local and container installation.
* Object Explorer - Added Ledger icons and scripting support to Object Explorer for Ledger objects.
@@ -95,7 +184,7 @@
## Version 1.38.0
* Release date: July 27, 2022
* Release status: General Availability
## What's new in 1.38.0
### What's new in 1.38.0
* New Features:
* VS Code merges to 1.62 - This release includes updates to VS Code from the three previous VS Code releases. Read [their release notes](https://code.visualstudio.com/updates/v1_62) to learn more.
* Table Designer - New column added to Table Designer for easier access to additional actions specific to individual rows.
@@ -123,7 +212,7 @@
## Version 1.37.0
* Release date: June 15, 2022
* Release status: General Availability
## What's new in this version
### What's new in this version
* New Features:
* Backup & Restore - Backup & Restore to URL is now available in preview for Azure SQL Managed Instances.
* Table Designer - Added API to support computed column capabilities on Table Designer.
@@ -146,7 +235,7 @@
## Version 1.36.2
* Release date: May 20, 2022
* Release status: General Availability
## What's new in this version
### What's new in this version
- Fix connectivity issue with PBI data source
- Fix query plan zoom and icon issues
- Issues fixed in this release https://github.com/microsoft/azuredatastudio/milestone/89?closed=1
@@ -154,14 +243,14 @@
## Version 1.36.1
* Release date: April 22, 2022
* Release status: General Availability
## What's new in this version
### What's new in this version
* April Hotfix addressing these issues https://github.com/microsoft/azuredatastudio/milestone/88?closed=1.
* Hotfix RCA - https://github.com/microsoft/azuredatastudio/wiki/ADS-April-2022-Hotfix-RCA
## Version 1.36.0
* Release date: April 20, 2022
* Release status: General Availability
## What's new in this version
### What's new in this version
- General Availability of the Azure SQL Migration Extension for ADS
- Support for .NET Interactive Notebooks Extension
- New Table Designer Features including support for System Versioned, Graph and Memory Optomized Tables
@@ -171,14 +260,14 @@
## Version 1.35.1
* Release date: March 17, 2022
* Release status: General Availability
## Hotfix release
### Hotfix release
- Fix for [Excel number format #18615](https://github.com/microsoft/azuredatastudio/issues/18615)
- Fix for [Geometry Data Type Returned as Unknown Charset in Results Grid #18630](https://github.com/microsoft/azuredatastudio/issues/18630)
## Version 1.35.0
## Version 1.35.0
* Release date: February 24, 2022
* Release status: General Availability
## What's new in this version
### What's new in this version
* New Features:
* Table Designer - Added functionality for creation and management of tables for SQL Servers. Built using DacFx framework
* Query Plan Viewer - Added functionality for users to view a graphic view of estimated and actual query plans without need for an extension
@@ -191,7 +280,7 @@
## Version 1.34.0
* Release date: December 15, 2021
* Release status: General Availability
## What's new in this version
### What's new in this version
* New Features:
* Added “Currently restoring backup file” in the migration progress details page of Azure SQL Migration extension when backup files location is Azure Storage blob container
* Enhancements to diagnostics in Azure SQL Migration extension
@@ -215,14 +304,14 @@
* Release date: Nov 4, 2021
* Release status: General Availability
## Hotfix release
### Hotfix release
- Fix for [#16535 Unable to See Saved Connections in Restricted Mode](https://github.com/microsoft/azuredatastudio/issues/17535)
- Fix for [#17579 Can't type in Notebook code cell after editing text cell](https://github.com/microsoft/azuredatastudio/issues/17579)
## Version 1.33.0
* Release date: October 27, 2021
* Release status: General Availability
## What's new in this version
### What's new in this version
* New Notebook Features:
* Notebook Views
* Split cell support
@@ -261,7 +350,7 @@
## Version 1.31.1
* Release date: July 29, 2021
* Release status: General Availability
## Hotfix Release
### Hotfix Release
- Fix for [#16436 Database Connection Toolbar Missing](https://github.com/microsoft/azuredatastudio/issues/16436)
## Version 1.31.0
@@ -552,7 +641,7 @@
* GA status for Big Data Cluster/SQL 2019 features [#8269](https://github.com/microsoft/azuredatastudio/issues/8269)
* Resolved [bugs and issues](https://github.com/microsoft/azuredatastudio/milestone/44?closed=1).
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
## Version 1.13.1
@@ -566,7 +655,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* General Availability release for Schema Compare and DACPAC extensions
* Resolved [bugs and issues](https://github.com/microsoft/azuredatastudio/milestone/43?closed=1).
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* aspnerd for `Use selected DB for import wizard schema list` [#7878](https://github.com/microsoft/azuredatastudio/pull/7878)
@@ -584,7 +673,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: October 2, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Announcing the Query History panel
* Improved Query Results Grid copy selection support
* TempDB page added to Server Reports extension
@@ -595,14 +684,14 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: September 10, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Resolved [bugs and issues](https://github.com/microsoft/azuredatastudio/milestone/41?closed=1).
## Version 1.10.0
* Release date: August 14, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* [SandDance](https://github.com/microsoft/SandDance) integration — A new way to interact with data. Download the extension [here](https://docs.microsoft.com/sql/azure-data-studio/sanddance-extension)
* Notebook improvements
* Better loading performance
@@ -618,7 +707,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: July 11, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Release of [SentryOne Plan Explorer Extension](https://www.sentryone.com/products/sentryone-plan-explorer-extension-azure-data-studio)
* **Schema Compare**
* Schema Compare File Support (.SCMP)
@@ -644,7 +733,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: June 6, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Initial release of the Database Admin Tool Extensions for Windows *Preview* extension
* Initial release of the Central Management Servers extension
* **Schema Compare**
@@ -665,24 +754,24 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: May 8, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Announcing Schema Compare *Preview* extension
* Tasks Panel UX improvement
* Announcing new Welcome page
* Resolved [bugs and issues](https://github.com/microsoft/azuredatastudio/milestone/31?closed=1).
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues.
## Version 1.6.0
* Release date: April 18, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Align with latest VS Code editor platform (currently 1.33.1)
* Resolved [bugs and issues](https://github.com/Microsoft/azuredatastudio/milestone/26?closed=1).
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* yamatoya for `fix the format (#4899)`
@@ -691,13 +780,13 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: March 18, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Announcing T-SQL Notebooks
* Announcing PostgreSQL extension
* Announcing SQL Server Dacpac extension
* Resolved [bugs and issues](https://github.com/Microsoft/azuredatastudio/milestone/25?closed=1).
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* GeoffYoung for `Fix sqlDropColumn description #4422`
@@ -706,7 +795,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: February 13, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* Added **Admin pack for SQL Server** extension pack to make it easier to install SQL Server admin-related extensions. This includes:
* [SQL Server Agent](https://docs.microsoft.com/en-us/sql/azure-data-studio/sql-server-agent-extension?view=sql-server-2017)
* [SQL Server Profiler](https://docs.microsoft.com/en-us/sql/azure-data-studio/sql-server-profiler-extension?view=sql-server-2017)
@@ -720,7 +809,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Results streaming enabled by default for long running queries
* Resolved [bugs and issues](https://github.com/Microsoft/azuredatastudio/milestone/23?closed=1).
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* AlexFsmn for `Added context menu for DBs in explorer view to backup & restore db. #2277`
@@ -731,7 +820,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: January 9, 2019
* Release status: General Availability
## What's new in this version
### What's new in this version
* #13 Feature Request: Azure Active Directory Authentication
* #1040 Stream initial query results as they become available
* #3298 Сan't add an azure account.
@@ -741,7 +830,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Updates to [SQL Server 2019 extension](https://docs.microsoft.com/sql/azure-data-studio/sql-server-2019-extension?view=sql-server-ver15)
* **sp_executesql to SQL** and **New Database** extensions
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* Tarig0 for `Add Routine_Type to CreateStoredProc fixes #3257 (#3286)`
@@ -753,7 +842,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: November 6, 2018
* Release status: General Availability
## What's new in this version
### What's new in this version
* Update to the SQL Server 2019 Preview extension
* Introducing Paste the Plan extension
* Introducing High Color queries extension, including SSMS editor theme
@@ -762,7 +851,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Upgrade SQL Tools Service to .Net Core 2.2 Preview 3 (for eventual AAD support)
* Fix customer reported GitHub issues
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* rdaniels6813 for `Add query plan theme support #3031`
@@ -776,12 +865,12 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: October 18, 2018
* Release status: General Availability
## What's new in this version
### What's new in this version
* Introducing the Azure Resource Explorer to browse Azure SQL Databases
* Improve Object Explorer and Query Editor connectivity robustness
* SQL Server 2019 and SQL Agent extension improvements
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* philoushka for `center the icon #2760`
@@ -793,7 +882,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: September 24, 2018
* Release status: General Availability
## What's new in this version
### What's new in this version
* Announcing the SQL Server 2019 Preview extension.
* Support for SQL Server 2019 preview features including Big Data Cluster support.
* Azure Data Studio Notebooks
@@ -804,7 +893,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Accessibility improvements for screen reader, keyboard navigation and high-contrast.
* Added Connection name option to provide an alternative display name in the Servers viewlet.
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* AlexFsmn `Feature: Ability to add connection name #2332`
@@ -814,7 +903,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: August 30, 2018
* Release status: Public Preview
## What's new in this version
### What's new in this version
* Announcing the SQL Server Import Extension
* SQL Server Profiler Session management
* SQL Server Agent improvements
@@ -822,7 +911,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Quality of Life improvements: Connection strings
* Fix many customer reported GitHub issues
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* SebastianPfliegel `Added more saveAsCsv options #2099`
@@ -840,7 +929,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: July 19, 2018
* Release status: Public Preview
## What's new in this version
### What's new in this version
* SQL Server Agent for Azure Data Studio extension improvements
* Added view of Alerts, Operators, and Proxies and icons on left pane
* Added dialogs for New Job, New Job Step, New Alert, and New Operator
@@ -861,7 +950,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: June 20, 2018
* Release status: Public Preview
## What's new in this version
### What's new in this version
* **SQL Server Profiler for Azure Data Studio *Preview*** extension initial release
* The new **SQL Data Warehouse** extension includes rich customizable dashboard widgets surfacing insights to your data warehouse. This unlocks key scenarios around managing and tuning your data warehouse to ensure it is optimized for consistent performance.
* **Edit Data "Filtering and Sorting"** support
@@ -874,7 +963,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: May 7, 2018
* Release status: Public Preview
## What's new in this version
### What's new in this version
The May release is focused on stabilization and bug fixes leading up to the Build conference. This build contains the following highlights.
* Announcing **Redgate SQL Search** extension available in Extension Manager
@@ -889,7 +978,7 @@ The May release is focused on stabilization and bug fixes leading up to the Buil
* Release date: April 25, 2018
* Release status: Public Preview
## What's new in this version
### What's new in this version
The April Public Preview release contains some of the following highlights.
* Improvements to SQL Agent *Preview* extension
@@ -904,7 +993,7 @@ The April Public Preview release contains some of the following highlights.
* Release date: March 28, 2017
* Release status: Public Preview
## What's new in this version
### What's new in this version
The March Public Preview release enables some key aspects of the Azure Data Studio
extensibility story. Here are some highlights in this release.
@@ -919,14 +1008,14 @@ extensibility story. Here are some highlights in this release.
* Release date: February 16, 2017
* Release status: Public Preview Hotfix 1
## What's new in this version
### What's new in this version
* Bug fix for `#717 Selecting partial query and hitting Cmd or Ctrl+C opens terminal with Error message`
## Version 0.26.6
* Release date: February 15, 2017
* Release status: Public Preview
## What's new in this version
### What's new in this version
The February release fixes several important customer reported issues, as well as various feature improvements. We've also introduced auto-update support in February which will simplify keeping updated with the lastest changes.
Here's some of the highlights in the February release.
@@ -946,7 +1035,7 @@ Here's some of the highlights in the February release.
* VS Code Editor 1.19 integration
* Update JustinPealing/html-query-plan component to pick-up several Query Plan viewer improvements
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* SebastianPfliegel for `Add cursor snippet (#475)`
@@ -957,7 +1046,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: January 17, 2017
* Release status: Public Preview
## What's new in this version
### What's new in this version
The January release focuses on addressing a few of the top upvoted feature suggestions, as well as fixing high-priority bugs. This release period coincides with holiday vacations, so the churn in this release is
relatively scoped.
@@ -972,7 +1061,7 @@ Here's some of the highlights in the January release.
* Fix missing Azure Account branding icon
* Change "Server name" to "Server" in Connection Dialog
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* alextercete for `Fix "No extension gallery service configured" error (#427)`
@@ -982,7 +1071,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Release date: December 19, 2017
* Release status: Public Preview
## What's new in this version
### What's new in this version
* Azure Integration with Create Firewall Rule
* Windows Setup, Linux DEB and Linux RPM installation packages
* Manage Dashboard visual layout editor
@@ -1006,7 +1095,7 @@ We would like to thank all our users who raised issues, and in particular the fo
* Allow expanding databases not in certain non-Online states
* Connection Dialog selects most common default authentication method based on platform
## Contributions and "thank you"
### Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* mwiedemeyer for `Fix #58: Default sort order for DB size widget (#111)`
* AlexTroshkin for `Show disconnect in context menu only when connectionProfile connected (#150)`

View File

@@ -8,27 +8,56 @@ Azure Data Studio is a data management tool that enables you to work with SQL Se
## **Download the latest Azure Data Studio release**
| Platform |
| --------------------------------------- |
| [Windows User Installer][win-user] |
| [Windows System Installer][win-system] |
| [Windows ZIP][win-zip] |
| [macOS ZIP][osx-zip] |
| [Linux TAR.GZ][linux-zip] |
| [Linux RPM][linux-rpm] |
| [Linux DEB][linux-deb] |
|Platform |Type |Download |
| --------|-----------------|----------------------- |
|Windows |User Installer |[64 bit][win-user]&emsp;[ARM][win-user-arm64] |
| |System Installer |[64 bit][win-system]&emsp;[ARM][win-system-arm64] |
| |.zip |[64 bit][win-zip]&emsp;[ARM][win-zip-arm64] |
|Linux |.tar.gz |[64 bit][linux-zip] |
| |.deb |[64 bit][linux-deb] |
| |.rpm |[64 bit][linux-rpm] |
|Mac |.zip |[Universal][osx-universal]&emsp;[Intel Chip][osx-zip]&emsp;[Apple Silicon][osx-arm64] |
[win-user]: https://go.microsoft.com/fwlink/?linkid=2222768
[win-system]: https://go.microsoft.com/fwlink/?linkid=2222769
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2223104
[win-user-arm64]: https://go.microsoft.com/fwlink/?linkid=2222660
[win-system-arm64]: https://go.microsoft.com/fwlink/?linkid=2222849
[win-zip-arm64]: https://go.microsoft.com/fwlink/?linkid=2222850
[osx-universal]: https://go.microsoft.com/fwlink/?linkid=2222873
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2222874
[osx-arm64]: https://go.microsoft.com/fwlink/?linkid=2222680
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2222918
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2223105
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2222875
Go to our [download page](https://aka.ms/getazuredatastudio) for more specific instructions.
## Try out the latest insiders build from `main`:
- [Windows User Installer - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/win32-x64-user/insider)
- [Windows System Installer - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/win32-x64/insider)
- [Windows ZIP - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/win32-x64-archive/insider)
- [macOS ZIP (Universal) - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/darwin-universal/insider)
- [macOS ZIP (Intel Chip) - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/darwin/insider)
- [macOS ZIP (Apple Silicon) - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/darwin-arm64/insider)
- [Linux TAR.GZ - **Insiders build**](https://azuredatastudio-update.azurewebsites.net/latest/linux-x64/insider)
## Try out the latest insiders build from `main` branch:
|Platform |Type |Download - Insiders Build |
| --------|-----------------|----------------------- |
|Windows |User Installer |[64 bit][in-win-user]&emsp;[ARM][in-win-user-arm64] |
| |System Installer |[64 bit][in-win-system]&emsp;[ARM][in-win-system-arm64] |
| |.zip |[64 bit][in-win-zip]&emsp;[ARM][in-win-zip-arm64] |
|Linux |.tar.gz |[64 bit][in-linux-zip] |
| |.deb |[64 bit][in-linux-deb] |
| |.rpm |[64 bit][in-linux-rpm] |
|Mac |.zip |[Universal][in-osx-universal]&emsp;[Intel Chip][in-osx-zip]&emsp;[Apple Silicon][in-osx-arm64] |
[in-win-user]: https://azuredatastudio-update.azurewebsites.net/latest/win32-x64-user/insider
[in-win-system]: https://azuredatastudio-update.azurewebsites.net/latest/win32-x64/insider
[in-win-zip]: https://azuredatastudio-update.azurewebsites.net/latest/win32-x64-archive/insider
[in-win-user-arm64]: https://azuredatastudio-update.azurewebsites.net/latest/win32-arm64-user/insider
[in-win-system-arm64]: https://azuredatastudio-update.azurewebsites.net/latest/win32-arm64/insider
[in-win-zip-arm64]: https://azuredatastudio-update.azurewebsites.net/latest/win32-arm64-archive/insider
[in-linux-zip]:https://azuredatastudio-update.azurewebsites.net/latest/linux-x64/insider
[in-linux-deb]:https://azuredatastudio-update.azurewebsites.net/latest/linux-deb-x64/insider
[in-linux-rpm]:https://azuredatastudio-update.azurewebsites.net/latest/linux-rpm-x64/insider
[in-osx-universal]: https://azuredatastudio-update.azurewebsites.net/latest/darwin-universal/insider
[in-osx-zip]: https://azuredatastudio-update.azurewebsites.net/latest/darwin/insider
[in-osx-arm64]: https://azuredatastudio-update.azurewebsites.net/latest/darwin-arm64/insider
See the [change log](https://github.com/Microsoft/azuredatastudio/blob/main/CHANGELOG.md) for additional details of what's in this release.
Go to our [download page](https://aka.ms/getazuredatastudio) for more specific instructions.
@@ -132,11 +161,3 @@ And of course, we'd like to thank the authors of all upstream dependencies. Ple
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](LICENSE.txt).
[win-user]: https://go.microsoft.com/fwlink/?linkid=2204567
[win-system]: https://go.microsoft.com/fwlink/?linkid=2204568
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2204772
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2204569
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2204773
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2204774
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2204570

View File

@@ -12,6 +12,7 @@ const files = [
'.build/langpacks/**/*.vsix',
'.build/extensions/**/*.vsix',
'.build/win32-x64/**/*.{exe,zip}',
'.build/win32-arm64/**/*.{exe,zip}',
'.build/linux/sha256hashes.txt',
'.build/linux/deb/amd64/deb/*.deb',
'.build/linux/rpm/x86_64/*.rpm',

View File

@@ -13,7 +13,8 @@ import * as fs from 'fs';
const files = [
'.build/langpacks/**/*.vsix', // langpacks
'.build/extensions/**/*.vsix', // external extensions
'.build/win32-x64/**/*.{exe,zip}', // windows binaries
'.build/win32-x64/**/*.{exe,zip}', // windows x64 binaries
'.build/win32-arm64/**/*.{exe,zip}', // windows arm64 binaries
'.build/linux/sha256hashes.txt', // linux hashes
'.build/linux/deb/amd64/deb/*.deb', // linux debs
'.build/linux/rpm/x86_64/*.rpm', // linux rpms

View File

@@ -48,6 +48,7 @@ stages:
variables:
NPM_CONFIG_ARCH: arm64
VSCODE_ARCH: arm64
AZDATA_RUNTIME: OSX_ARM64
# Do not run tests for arm64 build
RUN_TESTS: false
RUN_SMOKE_TESTS: false
@@ -106,17 +107,28 @@ stages:
timeoutInMinutes: 90
- stage: Windows
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], true))
condition: and(succeeded(), or(eq(variables['VSCODE_BUILD_WIN32'], true), eq(variables['VSCODE_BUILD_WIN32_ARM64'], true)))
pool:
vmImage: 'windows-2019'
dependsOn:
- Compile
jobs:
- job: Windows
- job: Windows_x64
variables:
VSCODE_ARCH: x64
steps:
- template: win32/sql-product-build-win32.yml
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))
timeoutInMinutes: 90
- job: Windows_ARM64
variables:
VSCODE_ARCH: arm64
AZDATA_RUNTIME: Windows_ARM64
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32_ARM64'], 'true'))
steps:
- template: win32/sql-product-build-win32.yml
timeoutInMinutes: 90
# disable due to invalid machine pool (karlb 3/9/2022)
# - job: Windows_Test
# condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))

View File

@@ -1,7 +1,7 @@
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$Arch = "x64"
$Arch = $env:VSCODE_ARCH
$Repo = "$(pwd)"
$Root = "$Repo\.."

View File

@@ -48,7 +48,7 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { node build/azure-pipelines/common/sql-computeNodeModulesCacheKey.js > .build/yarnlockhash }
exec { node build/azure-pipelines/common/sql-computeNodeModulesCacheKey.js $(VSCODE_ARCH) > .build/yarnlockhash }
displayName: Prepare yarn cache key
- task: Cache@2
@@ -69,6 +69,7 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$env:npm_config_arch="$(VSCODE_ARCH)"
$env:CHILD_CONCURRENCY="1"
exec { yarn --frozen-lockfile }
env:
@@ -102,8 +103,8 @@ steps:
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "package-rebuild-extensions" }
exec { yarn gulp "vscode-win32-x64-min-ci" }
exec { yarn gulp "vscode-win32-x64-inno-updater" }
exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-min-ci" }
exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" }
displayName: Build
env:
VSCODE_MIXIN_PASSWORD: $(github-distro-mixin-password)
@@ -117,7 +118,7 @@ steps:
vstsFeed: '2191dd5f-4aec-491b-ac50-568bbc331c8a'
vstsFeedPackage: '2e355f03-a97e-499a-949b-f02d62b6160c'
vstsPackageVersion: '*'
condition: and(succeeded(), eq(variables['VSCODE_QUALITY'], 'saw'))
condition: and(succeeded(), eq(variables['VSCODE_QUALITY'], 'saw'), ne(variables['VSCODE_ARCH'], 'arm64'))
- powershell: |
# Install TSGOps specific extensions
@@ -130,7 +131,7 @@ steps:
Move-Item $tempFilePath $zipFilePath
Expand-Archive $zipFilePath -DestinationPath $adsExtensionPath
displayName: Install SAW Extensions
condition: and(succeeded(), eq(variables['VSCODE_QUALITY'], 'saw'))
condition: and(succeeded(), eq(variables['VSCODE_QUALITY'], 'saw'), ne(variables['VSCODE_ARCH'], 'arm64'))
# - powershell: | @anthonydresser unit tests timeout never existing the node process
# . build/azure-pipelines/win32/exec.ps1
@@ -158,8 +159,27 @@ steps:
displayName: 'Sign out code'
inputs:
ConnectedServiceName: 'Code Signing'
FolderPath: '$(agent.builddirectory)/azuredatastudio-win32-x64'
Pattern: '*.exe,*.node,resources/app/node_modules.asar.unpacked/*.dll,swiftshader/*.dll,d3dcompiler_47.dll,vulkan-1.dll,libGLESv2.dll,ffmpeg.dll,libEGL.dll,Microsoft.SqlTools.Hosting.dll,Microsoft.SqlTools.ResourceProvider.Core.dll,Microsoft.SqlTools.ResourceProvider.DefaultImpl.dll,MicrosoftSqlToolsCredentials.dll,MicrosoftSqlToolsServiceLayer.dll,Newtonsoft.Json.dll,SqlSerializationService.dll,SqlToolsResourceProviderService.dll,Microsoft.SqlServer.*.dll,Microsoft.Data.Tools.Sql.BatchParser.dll'
FolderPath: '$(agent.builddirectory)/azuredatastudio-win32-$(VSCODE_ARCH)'
Pattern: |
*.exe
*.node
!**/node_modules/**/*
resources/app/node_modules.asar.unpacked/*.dll
d3dcompiler_47.dll
vulkan-1.dll
libGLESv2.dll
ffmpeg.dll
libEGL.dll
Microsoft.SqlTools.Hosting.dll
Microsoft.SqlTools.ResourceProvider.Core.dll
Microsoft.SqlTools.ResourceProvider.DefaultImpl.dll
MicrosoftSqlToolsCredentials.dll
MicrosoftSqlToolsServiceLayer.dll
Newtonsoft.Json.dll,SqlSerializationService.dll
SqlToolsResourceProviderService.dll
Microsoft.SqlServer.*.dll
Microsoft.Data.Tools.Sql.BatchParser.dll
useMinimatch: true
signConfigType: inlineSignParams
inlineOperation: |
[
@@ -212,9 +232,9 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "vscode-win32-x64-user-setup" }
exec { yarn gulp "vscode-win32-x64-system-setup" }
exec { yarn gulp "vscode-win32-x64-archive" }
exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-user-setup" }
exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-system-setup" }
exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-archive" }
displayName: Archive & User & System setup
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1

View File

@@ -41,7 +41,7 @@ steps:
inputs:
azureSubscription: 'ClientToolsInfra_670062 (88d5392f-a34f-4769-b405-f597fc533613)'
KeyVaultName: SqlToolsSecretStore
SecretsFilter: 'ads-integration-test-azure-server,ads-integration-test-azure-server-password,ads-integration-test-azure-server-username,ads-integration-test-bdc-server,ads-integration-test-bdc-server-password,ads-integration-test-bdc-server-username,ads-integration-test-standalone-server,ads-integration-test-standalone-server-password,ads-integration-test-standalone-server-username,ads-integration-test-standalone-server-2019,ads-integration-test-standalone-server-password-2019,ads-integration-test-standalone-server-username-2019'
SecretsFilter: 'ads-integration-test-azure-server,ads-integration-test-azure-server-password,ads-integration-test-azure-server-username,ads-integration-test-standalone-server,ads-integration-test-standalone-server-password,ads-integration-test-standalone-server-username,ads-integration-test-standalone-server-2019,ads-integration-test-standalone-server-password-2019,ads-integration-test-standalone-server-username-2019'
- powershell: |
. build/azure-pipelines/win32/exec.ps1
@@ -54,9 +54,6 @@ steps:
condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['RUN_INTEGRATION_TESTS'], 'false')))
displayName: Run stable tests
env:
BDC_BACKEND_USERNAME: $(ads-integration-test-bdc-server-username)
BDC_BACKEND_PWD: $(ads-integration-test-bdc-server-password)
BDC_BACKEND_HOSTNAME: $(ads-integration-test-bdc-server)
STANDALONE_SQL_USERNAME: $(ads-integration-test-standalone-server-username)
STANDALONE_SQL_PWD: $(ads-integration-test-standalone-server-password)
STANDALONE_SQL: $(ads-integration-test-standalone-server)

View File

@@ -8,32 +8,40 @@ Param(
$env:AZURE_STORAGE_ACCESS_KEY_2 = $storageKey
$env:AZURE_DOCUMENTDB_MASTERKEY = $documentDbKey
$ExeName = "AzureDataStudioSetup.exe"
$SystemExe = "$artifactsDir\win32-x64\system-setup\$ExeName"
$UserExe = "$artifactsDir\win32-x64\user-setup\$ExeName"
$UserExeName = "AzureDataStudioUserSetup.exe"
$ZipName = "azuredatastudio-win32-x64.zip"
$Zip = "$artifactsDir\win32-x64\archive\$ZipName"
$Flavors = "x64","arm64"
$FlavorSuffixes = "","-arm64"
$VersionJson = Get-Content -Raw -Path "$artifactsDir\version.json" | ConvertFrom-Json
$Version = $VersionJson.version
$Quality = $VersionJson.quality
$CommitId = $VersionJson.commit
For($i = 0; $i -lt $Flavors.Length; $i++)
{
$Flavor = $Flavors[$i]
$FlavorSuffix = $FlavorSuffixes[$i]
$ExeName = "AzureDataStudioSetup.exe"
$SystemExe = "$artifactsDir\win32-$Flavor\system-setup\$ExeName"
$UserExe = "$artifactsDir\win32-$Flavor\user-setup\$ExeName"
$UserExeName = "AzureDataStudioUserSetup.exe"
$ZipName = "azuredatastudio-win32-$Flavor.zip"
$Zip = "$artifactsDir\win32-$Flavor\archive\$ZipName"
$ZipUploadName = "azuredatastudio-windows-$Version"
$SetupUploadName = "azuredatastudio-windows-setup-$Version"
$UserUploadName = "azuredatastudio-windows-user-setup-$Version"
$VersionJson = Get-Content -Raw -Path "$artifactsDir\version.json" | ConvertFrom-Json
$Version = $VersionJson.version
$Quality = $VersionJson.quality
$CommitId = $VersionJson.commit
$assetPlatform = "win32-x64"
$ZipUploadName = "azuredatastudio-windows$FlavorSuffix-$Version"
$SetupUploadName = "azuredatastudio-windows$FlavorSuffix-setup-$Version"
$UserUploadName = "azuredatastudio-windows$FlavorSuffix-user-setup-$Version"
If (-NOT ($Quality -eq "stable")) {
$ZipUploadName = "$ZipUploadName-$Quality"
$SetupUploadName = "$SetupUploadName-$Quality"
$UserUploadName = "$UserUploadName-$Quality"
$assetPlatform = "win32-$Flavor"
If (-NOT ($Quality -eq "stable")) {
$ZipUploadName = "$ZipUploadName-$Quality"
$SetupUploadName = "$SetupUploadName-$Quality"
$UserUploadName = "$UserUploadName-$Quality"
}
node $sourcesDir/build/azure-pipelines/common/publish.js $Quality "$assetPlatform-archive" archive "$ZipUploadName.zip" $Version true $Zip $CommitId
node $sourcesDir/build/azure-pipelines/common/publish.js $Quality "$assetPlatform" setup "$SetupUploadName.exe" $Version true $SystemExe $CommitId
node $sourcesDir/build/azure-pipelines/common/publish.js $Quality "$assetPlatform-user" setup "$UserUploadName.exe" $Version true $UserExe $CommitId
}
node $sourcesDir/build/azure-pipelines/common/publish.js $Quality "$assetPlatform-archive" archive "$ZipUploadName.zip" $Version true $Zip $CommitId
node $sourcesDir/build/azure-pipelines/common/publish.js $Quality "$assetPlatform" setup "$SetupUploadName.exe" $Version true $SystemExe $CommitId
node $sourcesDir/build/azure-pipelines/common/publish.js $Quality "$assetPlatform-user" setup "$UserUploadName.exe" $Version true $UserExe $CommitId

View File

@@ -30,8 +30,7 @@ app.once('ready', () => {
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableWebSQL: false,
nativeWindowOpen: true
enableWebSQL: false
}
});
window.setMenuBarVisibility(false);

View File

@@ -28,17 +28,16 @@ async function main() {
const outAppPath = path.join(buildDir, `azuredatastudio-darwin-${arch}`, appName); // {{SQL CARBON EDIT}} - CHANGE VSCode to azuredatastudio
const productJsonPath = path.resolve(outAppPath, 'Contents', 'Resources', 'app', 'product.json');
// {{SQL CARBON EDIT}}
// Current STS arm64 builds doesn't work on osx-arm64, we need to use the x64 version of STS on osx-arm64 until the issue is fixed.
// Tracked by: https://github.com/microsoft/azuredatastudio/issues/20775
// makeUniversalApp function will complain if the x64 ADS and arm64 ADS have the same STS binaries, to workaround the issue, we need
// to delete STS from both of them and then copy it to the universal app.
// STS binaries for x64 and arm64 have different file count and cannot be combined
// Remove them from the package before the makeUniversalApp step and copy them to the universal package after it.
const stsPath = '/Contents/Resources/app/extensions/mssql/sqltoolsservice';
const tempSTSDir = path.join(buildDir, 'sqltoolsservice');
const x64STSDir = path.join(x64AppPath, stsPath);
const arm64STSDir = path.join(arm64AppPath, stsPath);
const targetSTSDirs = [x64STSDir, arm64STSDir];
// backup the x64 STS to a temporary directory, later it will be copied to the universal app directory.
// backup the STS folders to a temporary directory, later they will be copied to the universal app directory.
await fs.copy(x64STSDir, tempSTSDir);
await fs.copy(arm64STSDir, tempSTSDir);
// delete STS directories from both x64 ADS and arm64 ADS.
console.debug(`Removing SqlToolsService folders.`);
targetSTSDirs.forEach(async (dir) => {
@@ -78,14 +77,19 @@ async function main() {
});
await fs.writeJson(productJsonPath, productJson);
// Verify if native module architecture is correct
const findOutput = await (0, cross_spawn_promise_1.spawn)('find', [outAppPath, '-name', 'keytar.node']);
// {{SQL CARBON EDIT}} Some of our extensions have their own keytar so lookup
// only in core modules since this code doesn't work with multiple found modules.
// We're assuming here the intent is just to check a single file for validation and not
// needing to check any others since this currently is ignoring all other native modules.
const findOutput = await (0, cross_spawn_promise_1.spawn)('find', [outAppPath, '-name', 'keytar.node', '-regex', '.*node_modules.asar.unpacked.*',]);
const lipoOutput = await (0, cross_spawn_promise_1.spawn)('lipo', ['-archs', findOutput.replace(/\n$/, '')]);
if (lipoOutput.replace(/\n$/, '') !== 'x86_64 arm64') {
throw new Error(`Invalid arch, got : ${lipoOutput}`);
}
// {{SQL CARBON EDIT}}
console.debug(`Copying SqlToolsService to the universal app folder.`);
await fs.copy(tempSTSDir, path.join(outAppPath, stsPath), { overwrite: true });
await fs.copy(path.join(tempSTSDir, 'OSX'), path.join(outAppPath, stsPath, 'OSX'), { overwrite: true });
await fs.copy(path.join(tempSTSDir, 'OSX_ARM64'), path.join(outAppPath, stsPath, 'OSX_ARM64'), { overwrite: true });
}
if (require.main === module) {
main().catch(err => {

View File

@@ -34,17 +34,16 @@ async function main() {
const productJsonPath = path.resolve(outAppPath, 'Contents', 'Resources', 'app', 'product.json');
// {{SQL CARBON EDIT}}
// Current STS arm64 builds doesn't work on osx-arm64, we need to use the x64 version of STS on osx-arm64 until the issue is fixed.
// Tracked by: https://github.com/microsoft/azuredatastudio/issues/20775
// makeUniversalApp function will complain if the x64 ADS and arm64 ADS have the same STS binaries, to workaround the issue, we need
// to delete STS from both of them and then copy it to the universal app.
// STS binaries for x64 and arm64 have different file count and cannot be combined
// Remove them from the package before the makeUniversalApp step and copy them to the universal package after it.
const stsPath = '/Contents/Resources/app/extensions/mssql/sqltoolsservice';
const tempSTSDir = path.join(buildDir, 'sqltoolsservice');
const x64STSDir = path.join(x64AppPath, stsPath);
const arm64STSDir = path.join(arm64AppPath, stsPath);
const targetSTSDirs = [x64STSDir, arm64STSDir];
// backup the x64 STS to a temporary directory, later it will be copied to the universal app directory.
// backup the STS folders to a temporary directory, later they will be copied to the universal app directory.
await fs.copy(x64STSDir, tempSTSDir);
await fs.copy(arm64STSDir, tempSTSDir);
// delete STS directories from both x64 ADS and arm64 ADS.
console.debug(`Removing SqlToolsService folders.`);
targetSTSDirs.forEach(async dir => {
@@ -88,7 +87,11 @@ async function main() {
await fs.writeJson(productJsonPath, productJson);
// Verify if native module architecture is correct
const findOutput = await spawn('find', [outAppPath, '-name', 'keytar.node']);
// {{SQL CARBON EDIT}} Some of our extensions have their own keytar so lookup
// only in core modules since this code doesn't work with multiple found modules.
// We're assuming here the intent is just to check a single file for validation and not
// needing to check any others since this currently is ignoring all other native modules.
const findOutput = await spawn('find', [outAppPath, '-name', 'keytar.node', '-regex', '.*node_modules.asar.unpacked.*',]);
const lipoOutput = await spawn('lipo', ['-archs', findOutput.replace(/\n$/, '')]);
if (lipoOutput.replace(/\n$/, '') !== 'x86_64 arm64') {
throw new Error(`Invalid arch, got : ${lipoOutput}`);
@@ -96,7 +99,8 @@ async function main() {
// {{SQL CARBON EDIT}}
console.debug(`Copying SqlToolsService to the universal app folder.`);
await fs.copy(tempSTSDir, path.join(outAppPath, stsPath), { overwrite: true });
await fs.copy(path.join(tempSTSDir, 'OSX'), path.join(outAppPath, stsPath, 'OSX'), { overwrite: true });
await fs.copy(path.join(tempSTSDir, 'OSX_ARM64'), path.join(outAppPath, stsPath, 'OSX_ARM64'), { overwrite: true });
}
if (require.main === module) {

View File

@@ -47,6 +47,7 @@ module.exports.unicodeFilter = [
'!build/win32/**',
'!extensions/markdown-language-features/notebook-out/*.js',
'!extensions/markdown-math/notebook-out/**',
'!extensions/notebook-renderers/renderer-out/**',
'!extensions/php-language-features/src/features/phpGlobalFunctions.ts',
'!extensions/typescript-language-features/test-workspace/**',
'!extensions/vscode-api-tests/testWorkspace/**',
@@ -130,6 +131,7 @@ module.exports.indentationFilter = [
'!extensions/markdown-language-features/media/*.js',
'!extensions/markdown-language-features/notebook-out/*.js',
'!extensions/markdown-math/notebook-out/*.js',
'!extensions/notebook-renderers/renderer-out/*.js',
'!extensions/simple-browser/media/*.js',
// {{SQL CARBON EDIT}} Except for our stuff
@@ -152,8 +154,7 @@ module.exports.indentationFilter = [
'!extensions/sql-database-projects/src/test/baselines/*.json',
'!extensions/sql-database-projects/src/test/baselines/*.sqlproj',
'!extensions/sql-database-projects/BuildDirectory/SystemDacpacs/**',
'!extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts',
'!extensions/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts',
'!extensions/datavirtualization/scaleoutdataservice/**',
'!resources/linux/snap/electron-launch',
'!extensions/markdown-language-features/media/*.js',
'!extensions/simple-browser/media/*.js',
@@ -202,7 +203,6 @@ module.exports.copyrightFilter = [
'!extensions/import/flatfileimportservice/**',
'!extensions/kusto/src/prompts/**',
'!extensions/mssql/sqltoolsservice/**',
'!extensions/mssql/src/hdfs/webhdfs.ts',
'!extensions/mssql/src/prompts/**',
'!extensions/notebook/resources/jupyter_config/**',
'!extensions/notebook/src/intellisense/text.ts',
@@ -257,8 +257,6 @@ module.exports.tsFormattingFilter = [
'!extensions/html-language-features/server/lib/jquery.d.ts',
// {{SQL CARBON EDIT}}
'!extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts',
'!extensions/big-data-cluster/src/bigDataCluster/controller/tokenApiGenerated.ts',
'!src/vs/workbench/services/themes/common/textMateScopeMatcher.ts', // skip this because we have no plans on touching this and its not ours
'!src/vs/workbench/contrib/extensions/browser/extensionRecommendationsService.ts', // skip this because known issue
'!build/**/*'

View File

@@ -24,11 +24,6 @@ const product = require('../product.json');
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
// {{SQL CARBON EDIT}} - TODO: Import needs to be updated to work with langpacks.
const sqlLocalizedExtensions = [
'import',
];
// {{SQL CARBON EDIT}} Not doing this for us right now
// To save 250ms for each gulp startup, we are caching the result here
const compilations = glob.sync('**/tsconfig.json', {
@@ -74,7 +69,6 @@ const compilations = [
'vscode-api-tests/tsconfig.json',
'vscode-colorize-tests/tsconfig.json',
'vscode-custom-editor-tests/tsconfig.json',
'vscode-notebook-tests/tsconfig.json',
'vscode-test-resolver/tsconfig.json'
];
*/
@@ -161,7 +155,7 @@ const tasks = compilations.map(function (tsconfigFile) {
const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out));
const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(sqlLocalizedExtensions.includes(name), true); // {{SQL CARBON EDIT}}
const pipeline = createPipeline(false, true);
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts']));
const input = es.merge(nonts, pipeline.tsProjectSrc());

View File

@@ -448,7 +448,7 @@ function packagePkgTask(platform, arch, pkgTarget) {
// rebuild extensions that contain native npm modules or have conditional webpack rules
// when building with the web .yarnrc settings (e.g. runtime=node, etc.)
// this is needed to have correct module set published with desired ABI
const rebuildExtensions = ['big-data-cluster', 'mssql', 'notebook'];
const rebuildExtensions = ['mssql', 'notebook'];
const EXTENSIONS = path.join(REPO_ROOT, 'extensions');
function exec(cmdLine, cwd) {
console.log(cmdLine);

View File

@@ -40,8 +40,8 @@ const formatFiles = (some) => {
});
});
return gulp.src(some, {
base: '.'
})
base: '.'
})
.pipe(filter(f => !f.stat.isDirectory()))
.pipe(formatting);
@@ -102,19 +102,19 @@ gulp.task('package-external-extensions', task.series(
const extensionName = path.basename(extensionPath);
return { name: extensionName, path: extensionPath };
})
.filter(element => ext.vscodeExternalExtensions.indexOf(element.name) === -1) // VS Code external extensions are bundled into ADS so no need to create a normal VSIX for them
.map(element => {
const pkgJson = require(path.join(element.path, 'package.json'));
const vsixDirectory = path.join(root, '.build', 'extensions');
mkdirp.sync(vsixDirectory);
const packagePath = path.join(vsixDirectory, `${pkgJson.name}-${pkgJson.version}.vsix`);
console.info('Creating vsix for ' + element.path + ' result:' + packagePath);
return vsce.createVSIX({
cwd: element.path,
packagePath: packagePath,
useYarn: true
.filter(element => ext.vscodeExternalExtensions.indexOf(element.name) === -1) // VS Code external extensions are bundled into ADS so no need to create a normal VSIX for them
.map(element => {
const pkgJson = require(path.join(element.path, 'package.json'));
const vsixDirectory = path.join(root, '.build', 'extensions');
mkdirp.sync(vsixDirectory);
const packagePath = path.join(vsixDirectory, `${pkgJson.name}-${pkgJson.version}.vsix`);
console.info('Creating vsix for ' + element.path + ' result:' + packagePath);
return vsce.createVSIX({
cwd: element.path,
packagePath: packagePath,
useYarn: true
});
});
});
// Wait for all the initial VSIXes to be completed before making the VS Code ones since we'll be overwriting
// values in the package.json for those.
await Promise.all(vsixes);
@@ -133,15 +133,26 @@ gulp.task('package-external-extensions', task.series(
// And now use gulp-json-editor to modify the contents
const updateData = JSON.parse(fs.readFileSync(vscodeManifestFullPath)); // Read in the set of values to replace from package.vscode.json
Object.keys(updateData).forEach(key => {
data[key] = updateData[key];
if (key !== 'contributes') {
data[key] = updateData[key];
}
});
if(data.contributes?.menus){
if (data.contributes?.menus) {
// Remove ADS-only menus. This is a subset of the menus listed in https://github.com/microsoft/azuredatastudio/blob/main/src/vs/workbench/api/common/menusExtensionPoint.ts
// More can be added to the list as needed.
['objectExplorer/item/context', 'dataExplorer/context', 'dashboard/toolbar'].forEach(menu => {
delete data.contributes.menus[menu];
});
}
// Add any configuration properties from the package.vscode.json
// Currently only supports bringing over properties in the first config object found and doesn't support modifying the title
if (updateData.contributes?.configuration[0]?.properties) {
Object.keys(updateData.contributes.configuration[0].properties).forEach(key => {
data.contributes.configuration[0].properties[key] = updateData.contributes.configuration[0].properties[key];
});
}
return data;
}, { beautify: false }))
.pipe(gulp.dest(packageDir));

View File

@@ -125,9 +125,10 @@ const extensionsFilter = filter([
'**/azcli.xlf',
'**/azurecore.xlf',
'**/azurehybridtoolkit.xlf',
'**/big-data-cluster.xlf',
'**/azuremonitor.xlf',
'**/cms.xlf',
'**/dacpac.xlf',
'**/datavirtualization.xlf',
'**/git.xlf',
'**/data-workspace.xlf',
'**/import.xlf',

View File

@@ -104,8 +104,8 @@ function buildWin32Setup(arch, target) {
IncompatibleTargetAppId: { 'ia32': product.win32AppId, 'x64': product.win32x64AppId, 'arm64': product.win32arm64AppId }[arch],
IncompatibleArchAppId: { 'ia32': x64AppId, 'x64': ia32AppId, 'arm64': ia32AppId }[arch],
AppUserId: product.win32AppUserModelId,
ArchitecturesAllowed: { 'ia32': '', 'x64': 'x64', 'arm64': 'arm64' }[arch],
ArchitecturesInstallIn64BitMode: { 'ia32': '', 'x64': 'x64', 'arm64': 'arm64' }[arch],
ArchitecturesAllowed: { 'ia32': '', 'x64': 'x64', 'arm64': 'arm64 x64' }[arch], //{{SQL CARBON EDIT}} - we still have x64 binaries in SqlToolsService, need to allow x64 binaries for arm64 arch.
ArchitecturesInstallIn64BitMode: { 'ia32': '', 'x64': 'x64', 'arm64': 'arm64 x64' }[arch], //{{SQL CARBON EDIT}} - same as line above.
SourceDir: sourcePath,
RepoDir: repoPath,
OutputDir: outputPath,

View File

@@ -241,7 +241,6 @@ const excludedExtensions = [
'vscode-test-resolver',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
'vscode-notebook-tests',
'vscode-custom-editor-tests',
'integration-tests', // {{SQL CARBON EDIT}}
];
@@ -261,9 +260,9 @@ const externalExtensions = [
'azuremonitor',
'cms',
'dacpac',
'datavirtualization',
'import',
'kusto',
'liveshare',
'machine-learning',
'profiler',
'query-history',
@@ -282,7 +281,6 @@ exports.vscodeExternalExtensions = [
];
// extensions that require a rebuild since they have native parts
const rebuildExtensions = [
'big-data-cluster',
'mssql'
];
const marketplaceWebExtensionsExclude = new Set([
@@ -475,7 +473,7 @@ const esbuildMediaScripts = [
'markdown-language-features/esbuild-notebook.js',
'markdown-language-features/esbuild-preview.js',
'markdown-math/esbuild.js',
// 'notebook-renderers/esbuild.js', {{SQL CARBON EDIT}} We don't have this extension
'notebook-renderers/esbuild.js',
'simple-browser/esbuild-preview.js',
];
async function webpackExtensions(taskName, isWatch, webpackConfigLocations) {

View File

@@ -285,7 +285,6 @@ const excludedExtensions = [
'vscode-test-resolver',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
'vscode-notebook-tests',
'vscode-custom-editor-tests',
'integration-tests', // {{SQL CARBON EDIT}}
];
@@ -306,9 +305,9 @@ const externalExtensions = [
'azuremonitor',
'cms',
'dacpac',
'datavirtualization',
'import',
'kusto',
'liveshare',
'machine-learning',
'profiler',
'query-history',
@@ -329,7 +328,6 @@ export const vscodeExternalExtensions = [
// extensions that require a rebuild since they have native parts
const rebuildExtensions = [
'big-data-cluster',
'mssql'
];
@@ -573,7 +571,7 @@ const esbuildMediaScripts = [
'markdown-language-features/esbuild-notebook.js',
'markdown-language-features/esbuild-preview.js',
'markdown-math/esbuild.js',
// 'notebook-renderers/esbuild.js', {{SQL CARBON EDIT}} We don't have this extension
'notebook-renderers/esbuild.js',
'simple-browser/esbuild-preview.js',
];

View File

@@ -169,35 +169,43 @@ const textFields = {
const VSCODEExtensions = [
"bat",
"configuration-editing",
"csharp",
"dart",
"docker",
"git-ui",
"fsharp",
"git",
"github-authentication",
"git-base",
"github",
"github-authentication",
"html",
"image-preview",
"json-language-features",
"javascript",
"json",
"json-language-features",
"julia",
"markdown-basics",
"markdown-language-features",
"markdown-math",
"merge-conflict",
"microsoft-authentication",
"notebook-renderers",
"powershell",
"python",
"r",
"search-result",
"simple-browser",
"sql",
"theme-abyss",
"theme-defaults",
"theme-kimbie-dark",
"theme-monokai-dimmed",
"theme-monokai",
"theme-monokai-dimmed",
"theme-quietlight",
"theme-red",
"theme-seti",
"theme-solarized-dark",
"theme-solarized-light",
"theme-tomorrow-night-blue",
"typescript-basics",
"xml",
"yaml"
];

View File

@@ -187,35 +187,43 @@ const textFields = {
const VSCODEExtensions = [
"bat",
"configuration-editing",
"csharp",
"dart",
"docker",
"git-ui",
"fsharp",
"git",
"github-authentication",
"git-base",
"github",
"github-authentication",
"html",
"image-preview",
"json-language-features",
"javascript",
"json",
"json-language-features",
"julia",
"markdown-basics",
"markdown-language-features",
"markdown-math",
"merge-conflict",
"microsoft-authentication",
"notebook-renderers",
"powershell",
"python",
"r",
"search-result",
"simple-browser",
"sql",
"theme-abyss",
"theme-defaults",
"theme-kimbie-dark",
"theme-monokai-dimmed",
"theme-monokai",
"theme-monokai-dimmed",
"theme-quietlight",
"theme-red",
"theme-seti",
"theme-solarized-dark",
"theme-solarized-light",
"theme-tomorrow-night-blue",
"typescript-basics",
"xml",
"yaml"
];

View File

@@ -65,6 +65,7 @@ exports.referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.8)(64bit)',
'libc.so.6(GLIBC_2.9)(64bit)',
'libcairo.so.2()(64bit)',
'libcups.so.2()(64bit)',
'libcurl.so.4()(64bit)',
'libdbus-1.so.3()(64bit)',
'libdl.so.2()(64bit)',
@@ -147,6 +148,7 @@ exports.referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.8)',
'libc.so.6(GLIBC_2.9)',
'libcairo.so.2',
'libcups.so.2',
'libcurl.so.4()(64bit)',
'libdbus-1.so.3',
'libdl.so.2',
@@ -237,6 +239,7 @@ exports.referenceGeneratedDepsByArch = {
'libc.so.6()(64bit)',
'libc.so.6(GLIBC_2.17)(64bit)',
'libcairo.so.2()(64bit)',
'libcups.so.2()(64bit)',
'libcurl.so.4()(64bit)',
'libdbus-1.so.3()(64bit)',
'libdbus-1.so.3(LIBDBUS_1_3)(64bit)',

View File

@@ -65,6 +65,7 @@ export const referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.8)(64bit)',
'libc.so.6(GLIBC_2.9)(64bit)',
'libcairo.so.2()(64bit)',
'libcups.so.2()(64bit)',
'libcurl.so.4()(64bit)',
'libdbus-1.so.3()(64bit)',
'libdl.so.2()(64bit)',
@@ -147,6 +148,7 @@ export const referenceGeneratedDepsByArch = {
'libc.so.6(GLIBC_2.8)',
'libc.so.6(GLIBC_2.9)',
'libcairo.so.2',
'libcups.so.2',
'libcurl.so.4()(64bit)',
'libdbus-1.so.3',
'libdl.so.2',
@@ -237,6 +239,7 @@ export const referenceGeneratedDepsByArch = {
'libc.so.6()(64bit)',
'libc.so.6(GLIBC_2.17)(64bit)',
'libcairo.so.2()(64bit)',
'libcups.so.2()(64bit)',
'libcurl.so.4()(64bit)',
'libdbus-1.so.3()(64bit)',
'libdbus-1.so.3(LIBDBUS_1_3)(64bit)',

View File

@@ -17,11 +17,11 @@ exports.dirs = [
'extensions/azurecore',
'extensions/azurehybridtoolkit',
'extensions/azuremonitor',
'extensions/big-data-cluster',
'extensions/cms',
'extensions/configuration-editing',
'extensions/dacpac',
'extensions/data-workspace',
'extensions/datavirtualization',
'extensions/git',
'extensions/git-base',
'extensions/github',
@@ -29,10 +29,10 @@ exports.dirs = [
'extensions/image-preview',
'extensions/import',
'extensions/integration-tests',
'extensions/ipynb',
'extensions/json-language-features',
'extensions/json-language-features/server',
'extensions/kusto',
'extensions/liveshare',
'extensions/machine-learning',
'extensions/markdown-language-features',
'extensions/markdown-math',
@@ -40,6 +40,7 @@ exports.dirs = [
'extensions/microsoft-authentication',
'extensions/mssql',
'extensions/notebook',
'extensions/notebook-renderers',
'extensions/profiler',
'extensions/python',
'extensions/query-history',

View File

@@ -130,7 +130,7 @@ color-support@^1.1.2:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
console-control-strings@^1.0.0, console-control-strings@^1.1.0:
version "1.1.0"
@@ -226,9 +226,9 @@ has-unicode@^2.0.1:
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
http-cache-semantics@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-proxy-agent@^4.0.1:
version "4.0.1"
@@ -339,9 +339,9 @@ make-fetch-happen@^9.1.0:
ssri "^8.0.0"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"

View File

@@ -81,6 +81,7 @@
},
"dependencies": {},
"resolutions": {
"json-schema": "0.4.0"
"json-schema": "0.4.0",
"jsonwebtoken": "9.0.0"
}
}

View File

@@ -1972,9 +1972,9 @@ htmlparser2@^8.0.1:
entities "^4.3.0"
http-cache-semantics@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-proxy-agent@^5.0.0:
version "5.0.0"
@@ -2199,9 +2199,9 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
jsonc-parser@^2.3.0:
version "2.3.1"
@@ -2229,21 +2229,15 @@ jsonparse@~1.2.0:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.2.0.tgz#5c0c5685107160e72fe7489bddea0b44c2bc67bd"
integrity sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=
jsonwebtoken@^8.5.1:
version "8.5.1"
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
jsonwebtoken@9.0.0, jsonwebtoken@^8.5.1:
version "9.0.0"
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz#d0faf9ba1cc3a56255fe49c0961a67e520c1926d"
integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==
dependencies:
jws "^3.2.2"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
lodash.isnumber "^3.0.3"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.once "^4.0.0"
lodash "^4.17.21"
ms "^2.1.1"
semver "^5.6.0"
semver "^7.3.8"
jsprim@^1.2.2:
version "1.4.2"
@@ -2323,52 +2317,17 @@ linkify-it@^3.0.1:
dependencies:
uc.micro "^1.0.1"
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==
lodash.isboolean@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==
lodash.isinteger@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==
lodash.isnumber@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
lodash.mergewith@^4.6.1:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
lodash.once@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
lodash.unescape@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c"
integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=
lodash@^4.17.10:
lodash@^4.17.10, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -2800,16 +2759,16 @@ punycode@^2.1.0, punycode@^2.1.1:
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@^6.9.1:
version "6.10.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e"
integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
dependencies:
side-channel "^1.0.4"
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
queue-microtask@^1.2.2:
version "1.2.3"
@@ -3032,7 +2991,7 @@ semver-compare@^1.0.0:
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver@^5.1.0, semver@^5.3.0, semver@^5.6.0:
semver@^5.1.0, semver@^5.3.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -3056,6 +3015,13 @@ semver@^7.3.5, semver@^7.3.7:
dependencies:
lru-cache "^6.0.0"
semver@^7.3.8:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
dependencies:
lru-cache "^6.0.0"
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"

View File

@@ -6,7 +6,7 @@
"git": {
"name": "chromium",
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
"commitHash": "e2aa76f05f3a6ccadbf43e37f5dfc195cc090b6a"
"commitHash": "16e28102fdf876ce6d136674ba66343ede07441f"
}
},
"licenseDetail": [
@@ -40,7 +40,7 @@
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"isOnlyProductionDependency": true,
"version": "98.0.4758.141"
"version": "100.0.4894.0"
},
{
"component": {
@@ -48,11 +48,11 @@
"git": {
"name": "nodejs",
"repositoryUrl": "https://github.com/nodejs/node",
"commitHash": "40ecd5601193c316e62e9216e8a4259130686208"
"commitHash": "acb71eab779fb56bf70e8a9e0cb2e82a089a87de"
}
},
"isOnlyProductionDependency": true,
"version": "16.13.0"
"version": "16.13.2"
},
{
"component": {
@@ -60,12 +60,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "73c87bcfc6e18428c21676d68f829364e6a7b15d"
"commitHash": "f887fa45dfaeeddfe20c9835ae7ca3a0823b661b"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "17.4.11"
"version": "19.1.8"
},
{
"component": {

View File

@@ -23,7 +23,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -23,9 +23,13 @@ Both of these are available as menu items on the context menu for nodes in the O
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Telemetry
This extension collects telemetry data, which is used to help understand how to improve the product. For example, this usage data helps to debug issues, such as slow start-up times, and to prioritize new features. While we appreciate the insights this data provides, we also know that not everyone wants to send usage data and you can disable telemetry as described in the Azure Data Studio [disable telemetry reporting](https://github.com/Microsoft/azuredatastudio/wiki/How-to-Disable-Telemetry-Reporting#how-to-disable-telemetry-reporting) documentation.
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -2,8 +2,8 @@
"downloadUrl": "https://sqlopsextensions.blob.core.windows.net/tools/ssmsmin/{#version#}/{#fileName#}",
"version": "16.0.19061.0",
"downloadFileNames": {
"Windows_64": "SsmsMin-16.0.19061.0-win-x64.zip",
"Windows_86": "SsmsMin-16.0.19061.0-win-x86.zip"
"Windows_86": "SsmsMin-16.0.19061.0-win-x86.zip",
"Windows": "SsmsMin-16.0.19061.0-win-x64.zip"
},
"installDirectory": "ssmsmin/{#platform#}/{#version#}",
"executableFiles": [

View File

@@ -2,7 +2,7 @@
"name": "admin-tool-ext-win",
"displayName": "%adminToolExtWin.displayName%",
"description": "%adminToolExtWin.description%",
"version": "0.1.1",
"version": "0.1.2",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/extensions/admin-tool-ext-win/license/Azure%20Data%20Studio%20Extension%20-%20Standalone%20(free)%20Use%20Terms.txt",
@@ -107,8 +107,8 @@
]
},
"dependencies": {
"@microsoft/ads-extension-telemetry": "^1.3.1",
"@microsoft/ads-service-downloader": "1.0.4",
"@microsoft/ads-extension-telemetry": "^2.0.0",
"@microsoft/ads-service-downloader": "^1.2.1",
"vscode-nls": "^4.1.2"
},
"devDependencies": {

View File

@@ -24,6 +24,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
const ssmsMinVer = JSON.parse(rawConfig.toString()).version;
exePath = path.join(context.extensionPath, 'ssmsmin', 'Windows', ssmsMinVer, 'ssmsmin.exe');
registerCommands(context);
context.subscriptions.push(TelemetryReporter);
}
}
@@ -51,7 +52,7 @@ function registerCommands(context: vscode.ExtensionContext): void {
*/
async function handleLaunchSsmsMinPropertiesDialogCommand(connectionContext?: azdata.ObjectExplorerContext): Promise<void> {
if (!connectionContext) {
TelemetryReporter.sendErrorEvent(TelemetryViews.SsmsMinProperties, 'NoConnectionContext');
TelemetryReporter.sendErrorEvent2(TelemetryViews.SsmsMinProperties, 'NoConnectionContext');
void vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForProp', "No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand"));
return;
}
@@ -63,7 +64,7 @@ async function handleLaunchSsmsMinPropertiesDialogCommand(connectionContext?: az
else if (connectionContext.nodeInfo) {
nodeType = connectionContext.nodeInfo.nodeType;
} else {
TelemetryReporter.sendErrorEvent(TelemetryViews.SsmsMinProperties, 'NoOENode');
TelemetryReporter.sendErrorEvent2(TelemetryViews.SsmsMinProperties, 'NoOENode');
void vscode.window.showErrorMessage(localize('adminToolExtWin.noOENode', "Could not determine Object Explorer node from connectionContext : {0}", JSON.stringify(connectionContext)));
return;
}
@@ -80,7 +81,7 @@ async function handleLaunchSsmsMinPropertiesDialogCommand(connectionContext?: az
async function handleLaunchSsmsMinGswDialogCommand(connectionContext?: azdata.ObjectExplorerContext): Promise<void> {
const action = 'GenerateScripts';
if (!connectionContext) {
TelemetryReporter.sendErrorEvent(TelemetryViews.SsmsMinGsw, 'NoConnectionContext');
TelemetryReporter.sendErrorEvent2(TelemetryViews.SsmsMinGsw, 'NoConnectionContext');
void vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForGsw', "No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand"));
return;
}
@@ -97,7 +98,7 @@ async function handleLaunchSsmsMinGswDialogCommand(connectionContext?: azdata.Ob
*/
async function launchSsmsDialog(action: string, connectionContext: azdata.ObjectExplorerContext): Promise<void> {
if (!connectionContext.connectionProfile) {
TelemetryReporter.sendErrorEvent(TelemetryViews.SsmsMinDialog, 'NoConnectionProfile');
TelemetryReporter.sendErrorEvent2(TelemetryViews.SsmsMinDialog, 'NoConnectionProfile');
void vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionProfile', "No connectionProfile provided from connectionContext : {0}", JSON.stringify(connectionContext)));
return;
}
@@ -111,7 +112,7 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
oeNode = await azdata.objectexplorer.getNode(connectionContext.connectionProfile.id, connectionContext.nodeInfo.nodePath);
}
else {
TelemetryReporter.sendErrorEvent(TelemetryViews.SsmsMinDialog, 'NoOENode');
TelemetryReporter.sendErrorEvent2(TelemetryViews.SsmsMinDialog, 'NoOENode');
void vscode.window.showErrorMessage(localize('adminToolExtWin.noOENode', "Could not determine Object Explorer node from connectionContext : {0}", JSON.stringify(connectionContext)));
return;
}
@@ -155,9 +156,10 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
runningProcesses.delete(proc.pid);
const err = stderr.toString();
if ((execException?.code !== 0) || err !== '') {
TelemetryReporter.sendErrorEvent(
TelemetryReporter.sendErrorEvent2(
TelemetryViews.SsmsMinDialog,
'LaunchSsmsDialogError',
execException,
execException ? execException?.code?.toString() : '',
getTelemetryErrorType(err));
}

View File

@@ -182,58 +182,27 @@
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7"
integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g==
"@microsoft/ads-extension-telemetry@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@microsoft/ads-extension-telemetry/-/ads-extension-telemetry-2.0.0.tgz#18ce267c7ed05c3b9dd99604a743e59f684c4e7c"
integrity sha512-hExe/akhgq15v/h19LAFqiKNV6N9VxD19lOwGxEmO55yoWUm3E2cYealxvoYCwGDmSJfCbjR9fz/KM8Yz4XWAA==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.4"
"@microsoft/applicationinsights-shims" "^2.0.1"
"@microsoft/dynamicproto-js" "^1.1.6"
"@vscode/extension-telemetry" "0.6.1"
"@microsoft/1ds-post-js@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216"
integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ==
dependencies:
"@microsoft/1ds-core-js" "3.2.3"
"@microsoft/applicationinsights-shims" "^2.0.1"
"@microsoft/dynamicproto-js" "^1.1.6"
"@microsoft/ads-extension-telemetry@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@microsoft/ads-extension-telemetry/-/ads-extension-telemetry-1.3.1.tgz#fa757ee88eac91b21c3a68562da6441c2ad15c39"
integrity sha512-8Zd7RwwN7ZufMoWFmc1bwzmQc1RV7/jf/Ua33YL1+P0ZwHoWFOhf/b0lwvAVzi9TB/7oD5zA5yv7A/i2sSTn6Q==
dependencies:
"@vscode/extension-telemetry" "^0.6.2"
"@microsoft/ads-service-downloader@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@microsoft/ads-service-downloader/-/ads-service-downloader-1.0.4.tgz#94e13461d655d0864cbf93978247cbd1097e7863"
integrity sha512-XVJ3RW4X5mzlPYeJnwTii5/6ywVib4UqCtrvxwRWSFe214Hi8jO2zNxzcpamiTCnHm2b8wZAuWGfsvIShbf/yg==
"@microsoft/ads-service-downloader@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@microsoft/ads-service-downloader/-/ads-service-downloader-1.2.1.tgz#b0216cb0486db6697ccf9e166ec81a9764bdb3aa"
integrity sha512-xB3VUaEYauXtm3zFko5clHnhF7l7QbX0AnnULGDrd2JANu1zThBR6toUQ9+zAMO+0KCHs71XLSuoP2A24G3WCw==
dependencies:
async-retry "^1.2.3"
eventemitter2 "^5.0.1"
http-proxy-agent "^2.1.0"
https-proxy-agent "^2.2.3"
http-proxy-agent "^5.0.0"
https-proxy-agent "^5.0.1"
mkdirp "1.0.4"
tar "^6.1.11"
tmp "^0.0.33"
yauzl "^2.10.0"
"@microsoft/applicationinsights-core-js@2.8.4":
version "2.8.4"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596"
integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ==
dependencies:
"@microsoft/applicationinsights-shims" "2.0.1"
"@microsoft/dynamicproto-js" "^1.1.6"
"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd"
integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ==
"@microsoft/azdata-test@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@microsoft/azdata-test/-/azdata-test-2.0.3.tgz#652984efa2f5adc56cdae9029a4d5f33446b54d3"
@@ -246,11 +215,6 @@
rimraf "^2.6.3"
typemoq "^2.1.0"
"@microsoft/dynamicproto-js@^1.1.6":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc"
integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg==
"@microsoft/vscodetestcover@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@microsoft/vscodetestcover/-/vscodetestcover-1.2.1.tgz#65f25132075a465a7a99688204486ee2b65ac07b"
@@ -266,6 +230,11 @@
istanbul-reports "^3.0.0"
mocha "^7.1.1"
"@tootallnate/once@2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
"@types/mocha@^7.0.2":
version "7.0.2"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce"
@@ -276,13 +245,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
"@vscode/extension-telemetry@^0.6.2":
version "0.6.2"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e"
integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w==
dependencies:
"@microsoft/1ds-core-js" "^3.2.3"
"@microsoft/1ds-post-js" "^3.2.3"
"@vscode/extension-telemetry@0.6.1":
version "0.6.1"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.1.tgz#f8d1f7145baf932b75077c48107edff48501fc14"
integrity sha512-Y4Oc8yGURGVF4WhCZcu+EVy+MAIeQDLDVeDlLn59H0C1w+7xr8dL2ZtDBioy+Hog1Edrd6zOwr3Na7xe1iC/UA==
agent-base@4, agent-base@^4.3.0:
version "4.3.0"
@@ -291,6 +257,13 @@ agent-base@4, agent-base@^4.3.0:
dependencies:
es6-promisify "^5.0.0"
agent-base@6:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
dependencies:
debug "4"
ansi-colors@3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813"
@@ -486,6 +459,13 @@ debug@3.2.6, debug@^3.1.0:
dependencies:
ms "^2.1.1"
debug@4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@^2.2.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -806,7 +786,16 @@ http-proxy-agent@^2.1.0:
agent-base "4"
debug "3.1.0"
https-proxy-agent@^2.2.3, https-proxy-agent@^2.2.4:
http-proxy-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==
dependencies:
"@tootallnate/once" "2"
agent-base "6"
debug "4"
https-proxy-agent@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
@@ -814,6 +803,14 @@ https-proxy-agent@^2.2.3, https-proxy-agent@^2.2.4:
agent-base "^4.3.0"
debug "^3.1.0"
https-proxy-agent@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
dependencies:
agent-base "6"
debug "4"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -1032,11 +1029,9 @@ jsesc@^2.5.1:
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
dependencies:
minimist "^1.2.5"
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
locate-path@^3.0.0:
version "3.0.0"
@@ -1180,7 +1175,7 @@ ms@2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
ms@^2.1.1:
ms@2.1.2, ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==

View File

@@ -17,7 +17,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -931,11 +931,9 @@ jsesc@^2.5.1:
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
dependencies:
minimist "^1.2.5"
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
locate-path@^3.0.0:
version "3.0.0"

View File

@@ -42,7 +42,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -2,7 +2,7 @@
"name": "arc",
"displayName": "%arc.displayName%",
"description": "%arc.description%",
"version": "1.7.0",
"version": "1.8.0",
"publisher": "Microsoft",
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
"icon": "images/extension.png",
@@ -54,7 +54,7 @@
{
"command": "arc.connectToController",
"title": "%command.connectToController.title%",
"icon": "$(disconnect)"
"icon": "$(plug)"
},
{
"command": "arc.removeController",

View File

@@ -190,3 +190,7 @@ export namespace cssStyles {
}
export const iconSize = '20px';
export const encryptOption = 'encrypt';
export const trustServerCertificateOption = 'trustServerCertificate';
export const encryptReadMoreLink = 'https://learn.microsoft.com/sql/database-engine/configure-windows/enable-encrypted-connections-to-the-database-engine';

View File

@@ -142,12 +142,21 @@ export const controllerPassword = localize('arc.controllerPassword', "Controller
export const username = localize('arc.username', "Username");
export const password = localize('arc.password', "Password");
export const rememberPassword = localize('arc.rememberPassword', "Remember Password");
export const encrypt = localize('arc.encrypt', "Encrypt");
export const encryptDescription = localize('arc.encryptDescription', "When true, SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed.");
export const trustServerCertificate = localize('arc.trustServerCertificate', "Trust Server Certificate");
export const trustServerCertDescription = localize('arc.trustServerCertDescription', "When true (and encrypt=true), SQL Server uses SSL encryption for all data sent between the client and server without validating the server certificate.");
export const enableTrustServerCert = localize('arc.enableTrustServerCert', "Enable Trust Server Certificate");
export const msgPromptSSLCertificateValidationFailed = localize('arc.msgPromptSSLCertificateValidationFailed', 'Encryption was enabled on this connection, review your SSL and certificate configuration for the target SQL Server, or set \'Trust server certificate\' to \'true\' in the settings file. Note: A self-signed certificate offers only limited protection and is not a recommended practice for production environments. Do you want to enable \'Trust server certificate\' on this connection and retry?');
export const connect = localize('arc.connect', "Connect");
export const readMore = localize('arc.readMore', "Read more");
export const cancel = localize('arc.cancel', "Cancel");
export const apply = localize('arc.apply', "Apply");
export const ok = localize('arc.ok', "Ok");
export const on = localize('arc.on', "On");
export const off = localize('arc.off', "Off");
export const booleantrue = localize('arc.booleantrue', "True");
export const booleanfalse = localize('arc.booleanfalse', "False");
export const notConfigured = localize('arc.notConfigured', "Not Configured");
// Database States - see https://docs.microsoft.com/sql/relational-databases/databases/database-states

View File

@@ -219,7 +219,10 @@ export class MiaaModel extends ResourceModel {
saveProfile: true,
id: '',
groupId: undefined,
options: {}
options: {
encrypt: this._miaaInfo.encrypt || true,
trustServerCertificate: this._miaaInfo.trustServerCertificate || false
}
};
}
@@ -240,6 +243,8 @@ export class MiaaModel extends ResourceModel {
this._activeConnectionId = connectionProfile.id;
this.info.connectionId = connectionProfile.id;
this._miaaInfo.userName = connectionProfile.userName;
this._miaaInfo.encrypt = connectionProfile.options.encrypt;
this._miaaInfo.trustServerCertificate = connectionProfile.options.trustServerCertificate;
await this._treeDataProvider.saveControllers();
}
@@ -270,6 +275,5 @@ export class MiaaModel extends ResourceModel {
this._databaseTimeWindow.set(dbName, ['', '']);
}
}
}
}

View File

@@ -20,7 +20,9 @@ declare module 'arc' {
}
export type MiaaResourceInfo = ResourceInfo & {
userName?: string
userName?: string,
encrypt?: string,
trustServerCertificate?: boolean
};
export type PGResourceInfo = ResourceInfo & {

View File

@@ -8,11 +8,15 @@ import * as vscode from 'vscode';
import { Deferred } from '../../common/promise';
import * as loc from '../../localizedConstants';
import { createCredentialId } from '../../common/utils';
import { credentialNamespace } from '../../constants';
import * as constants from '../../constants';
import { InitializingComponent } from '../components/initializingComponent';
import { ResourceModel } from '../../models/resourceModel';
import { ControllerModel } from '../../models/controllerModel';
export interface IReconnectAction {
(profile: azdata.IConnectionProfile): Promise<boolean>;
}
export abstract class ConnectToSqlDialog extends InitializingComponent {
protected modelBuilder!: azdata.ModelBuilder;
@@ -20,6 +24,9 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
protected usernameInputBox!: azdata.InputBoxComponent;
protected passwordInputBox!: azdata.InputBoxComponent;
protected rememberPwCheckBox!: azdata.CheckBoxComponent;
protected encryptSelectBox!: azdata.DropDownComponent;
protected trustServerCertificateSelectBox!: azdata.DropDownComponent;
private options: { [name: string]: any } = {};
protected _completionPromise = new Deferred<azdata.IConnectionProfile | undefined>();
@@ -29,7 +36,11 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
}
public showDialog(dialogTitle: string, connectionProfile?: azdata.IConnectionProfile): azdata.window.Dialog {
const dialog = azdata.window.createModelViewDialog(dialogTitle);
const dialog = azdata.window.createModelViewDialog(dialogTitle, undefined, 'narrow');
const trueCategory: azdata.CategoryValue = { displayName: loc.booleantrue, name: 'true' }
const falseCategory: azdata.CategoryValue = { displayName: loc.booleanfalse, name: 'false' }
const booleanCategoryValues: azdata.CategoryValue[] = [trueCategory, falseCategory];
dialog.cancelButton.onClick(() => this.handleCancel());
dialog.registerContent(async view => {
this.modelBuilder = view.modelBuilder;
@@ -47,13 +58,22 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
.withProps({
inputType: 'password',
value: connectionProfile?.password
})
.component();
}).component();
this.rememberPwCheckBox = this.modelBuilder.checkBox()
.withProps({
label: loc.rememberPassword,
checked: connectionProfile?.savePassword
}).component();
this.encryptSelectBox = this.modelBuilder.dropDown()
.withProps({
values: booleanCategoryValues,
value: connectionProfile?.options[constants.encryptOption] ? trueCategory : falseCategory
}).component();
this.trustServerCertificateSelectBox = this.modelBuilder.dropDown()
.withProps({
values: booleanCategoryValues,
value: connectionProfile?.options[constants.trustServerCertificateOption] ? trueCategory : falseCategory
}).component();
let formModel = this.modelBuilder.formContainer()
.withFormItems([{
@@ -73,6 +93,18 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
}, {
component: this.rememberPwCheckBox,
title: ''
}, {
component: this.encryptSelectBox,
title: loc.encrypt,
layout: {
info: loc.encryptDescription,
}
}, {
component: this.trustServerCertificateSelectBox,
title: loc.trustServerCertificate,
layout: {
info: loc.trustServerCertDescription,
}
}
],
title: ''
@@ -94,6 +126,10 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
if (!this.serverNameInputBox.value || !this.usernameInputBox.value || !this.passwordInputBox.value) {
return false;
}
this.options.encrypt = this.encryptSelectBox.value;
this.options.trustServerCertificate = this.trustServerCertificateSelectBox.value;
const connectionProfile: azdata.IConnectionProfile = {
serverName: this.serverNameInputBox.value,
databaseName: '',
@@ -109,10 +145,15 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
groupId: undefined,
options: this.options
};
return await this.connect(connectionProfile);
}
private async connect(connectionProfile: azdata.IConnectionProfile): Promise<boolean> {
const result = await azdata.connection.connect(connectionProfile, false, false);
if (result.connected) {
connectionProfile.id = result.connectionId!;
const credentialProvider = await azdata.credentials.getProvider(credentialNamespace);
const credentialProvider = await azdata.credentials.getProvider(constants.credentialNamespace);
if (connectionProfile.savePassword) {
await credentialProvider.saveCredential(createCredentialId(this._controllerModel.info.id, this._model.info.resourceType, this._model.info.name), connectionProfile.password);
} else {
@@ -123,10 +164,40 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
}
else {
vscode.window.showErrorMessage(this.connectionFailedMessage(result.errorMessage));
return false;
// Show error with instructions for MSSQL Provider Encryption error code -2146893019 thrown by SqlClient when certificate validation fails.
if (result.errorCode === -2146893019) {
return this.showInstructionTextAsWarning(connectionProfile, async updatedConnection => {
return await this.connect(updatedConnection);
});
} else {
return false;
}
}
}
private async showInstructionTextAsWarning(profile: azdata.IConnectionProfile, reconnectAction: IReconnectAction): Promise<boolean> {
while (true) {
const selection = await vscode.window.showWarningMessage(
loc.msgPromptSSLCertificateValidationFailed,
{ modal: false },
...[
loc.enableTrustServerCert,
loc.readMore,
loc.cancel
]);
if (selection === loc.enableTrustServerCert) {
profile.options.encrypt = true;
profile.options.trustServerCertificate = true;
return await reconnectAction(profile);
} else if (selection === loc.readMore) {
vscode.env.openExternal(vscode.Uri.parse(constants.encryptReadMoreLink));
// Show the dialog again so the user can still pick yes or no after they've read the docs
continue;
} else {
return false;
}
}
}
protected abstract get providerName(): string;
protected abstract connectionFailedMessage(error: any): string;

View File

@@ -110,10 +110,15 @@ export class ControllerTreeNode extends TreeNode {
node = new PostgresTreeNode(postgresModel, this.model);
break;
case ResourceType.sqlManagedInstances:
// Fill in the username too if we already have it
(resourceInfo as MiaaResourceInfo).userName = (this.model.info.resources.find(info =>
// Fill in the username and connection properties too if we already have them
let miaaResourceInfo = this.model.info.resources.find(info =>
info.name === resourceInfo.name &&
info.resourceType === resourceInfo.resourceType) as MiaaResourceInfo)?.userName;
info.resourceType === resourceInfo.resourceType) as MiaaResourceInfo;
if (miaaResourceInfo) {
(resourceInfo as MiaaResourceInfo).userName = miaaResourceInfo.userName;
(resourceInfo as MiaaResourceInfo).encrypt = miaaResourceInfo.encrypt;
(resourceInfo as MiaaResourceInfo).trustServerCertificate = miaaResourceInfo.trustServerCertificate;
}
const miaaModel = new MiaaModel(this.model, resourceInfo, registration, this._treeDataProvider);
node = new MiaaTreeNode(miaaModel, this.model);
break;

View File

@@ -984,11 +984,9 @@ jsesc@^2.5.1:
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
dependencies:
minimist "^1.2.5"
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
just-extend@^4.0.2:
version "4.1.0"

View File

@@ -8,7 +8,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -14,7 +14,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -2,7 +2,7 @@
"name": "azcli",
"displayName": "%azcli.arc.displayName%",
"description": "%azcli.arc.description%",
"version": "1.7.0",
"version": "1.8.0",
"publisher": "Microsoft",
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
"icon": "images/extension.png",

View File

@@ -1203,11 +1203,9 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
dependencies:
minimist "^1.2.5"
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
jsprim@^1.2.2:
version "1.4.2"
@@ -1535,9 +1533,9 @@ punycode@^2.1.0, punycode@^2.1.1:
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
readdirp@~3.2.0:
version "3.2.0"

View File

@@ -12,7 +12,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/privacystatement) describes the privacy statement of this software.
To learn more about our Privacy Statement visit [this link](https://go.microsoft.com/fwlink/?LinkID=824704).
## License

View File

@@ -19,7 +19,10 @@ const externals = {
'universalify': 'commonjs universalify',
'@azure/arm-subscriptions': 'commonjs @azure/arm-subscriptions',
'@azure/arm-resourcegraph': 'commonjs @azure/arm-resourcegraph',
'@azure/storage-blob': 'commonjs @azure/storage-blob'
'@azure/storage-blob': 'commonjs @azure/storage-blob',
'@azure/msal-node': 'commonjs @azure/msal-node',
'@azure/msal-node-extensions': 'commonjs @azure/msal-node-extensions',
'msal': 'commonjs msal'
};
// conditionally add ws if we are going to be running in a node environment

View File

@@ -4,19 +4,9 @@
"default": false,
"description": "%config.enableUsGovCloudDescription%"
},
"accounts.azure.enableUsNatCloud": {
"type": "boolean",
"default": false,
"description": "%config.enableUsNatCloudDescription%"
},
"accounts.azure.enableChinaCloud": {
"type": "boolean",
"default": false,
"description": "%config.enableChinaCloudDescription%"
},
"accounts.azure.enableGermanyCloud": {
"type": "boolean",
"default": false,
"description": "%config.enableGermanyCloudDescription%"
}
}

View File

@@ -18,12 +18,12 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
},
"contributes": {
"resourceViewResources": [
{
@@ -63,16 +63,6 @@
"default": false,
"description": "%config.enableUsGovCloudDescription%"
},
"accounts.azure.cloud.enableUsNatCloud": {
"type": "boolean",
"default": false,
"description": "%config.enableUsNatCloudDescription%"
},
"accounts.azure.cloud.enableGermanyCloud": {
"type": "boolean",
"default": false,
"description": "%config.enableGermanyCloudDescription%"
},
"accounts.azure.cloud.enableChinaCloud": {
"type": "boolean",
"default": false,
@@ -124,6 +114,19 @@
"Verbose",
"All"
]
},
"azure.authenticationLibrary": {
"type": "string",
"description": "%config.authenticationLibrary%",
"default": "MSAL",
"enum": [
"ADAL",
"MSAL"
],
"enumDescriptions": [
"Azure Active Directory Authentication Library",
"Microsoft Authentication Library"
]
}
}
}
@@ -275,22 +278,22 @@
},
{
"command": "azure.resource.azureview.refresh",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:account|subscription|databaseContainer|databaseServerContainer)$/",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:account|subscription|databaseContainer|databaseServerContainer|synapseSqlPoolContainer|synapseWorkspaceContainer)$/",
"group": "inline"
},
{
"command": "azure.resource.azureview.refresh",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:account|subscription|databaseContainer|databaseServerContainer)$/",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:account|subscription|databaseContainer|databaseServerContainer|synapseSqlPoolContainer|synapseWorkspaceContainer)$/",
"group": "azurecore"
},
{
"command": "azure.resource.connectsqlserver",
"when": "viewItem == azure.resource.itemType.databaseServer || viewItem == azure.resource.itemType.database || viewItem == azure.resource.itemType.sqlInstance",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:database|databaseServer|synapseSqlPool|synapseWorkspace|sqlInstance)$/",
"group": "inline"
},
{
"command": "azure.resource.connectsqlserver",
"when": "viewItem == azure.resource.itemType.databaseServer || viewItem == azure.resource.itemType.database || viewItem == azure.resource.itemType.sqlInstance",
"when": "viewItem =~ /^azure\\.resource\\.itemType\\.(?:database|databaseServer|synapseSqlPool|synapseWorkspace|sqlInstance)$/",
"group": "azurecore"
},
{
@@ -347,8 +350,11 @@
"dependencies": {
"@azure/arm-resourcegraph": "^4.0.0",
"@azure/arm-subscriptions": "^3.0.0",
"@azure/msal-node": "^1.9.0",
"@azure/storage-blob": "^12.6.0",
"axios": "^0.27.2",
"lockfile": "1.0.4",
"msal": "^1.4.16",
"node-fetch": "^2.6.7",
"qs": "^6.9.1",
"universalify": "^0.1.2",
@@ -356,9 +362,12 @@
"ws": "^7.4.6"
},
"devDependencies": {
"@microsoft/azdata-test": "^2.0.3",
"@microsoft/vscodetestcover": "^1.2.1",
"@types/keytar": "4.4.0",
"@types/lockfile": "^1.0.2",
"@types/mocha": "^7.0.2",
"@types/node": "^12.11.7",
"@types/node": "^12.20.55",
"@types/qs": "^6.9.1",
"@types/request": "^2.48.1",
"@types/sinon": "^9.0.4",
@@ -366,8 +375,9 @@
"mocha": "^7.1.1",
"should": "^13.2.1",
"sinon": "^9.0.2",
"typemoq": "^2.1.0",
"@microsoft/vscodetestcover": "^1.2.1",
"@microsoft/azdata-test": "^2.0.3"
"typemoq": "^2.1.0"
},
"resolutions": {
"jsonwebtoken": "9.0.0"
}
}

View File

@@ -31,6 +31,7 @@
"config.azureDeviceCodeMethod": "Device Code Method",
"config.noSystemKeychain": "Disable system keychain integration. Credentials will be stored in a flat file in the user's home directory.",
"config.piiLogging": "Should Personally Identifiable Information (PII) be logged in the Azure Accounts output channel and the output channel log file.",
"config.loggingLevel": "[Optional] The verbosity of logging for the Azure Accounts extension."
"config.loggingLevel": "[Optional] The verbosity of logging for the Azure Accounts extension.",
"config.authenticationLibrary": "The library used for the AAD auth flow. Please restart ADS after changing this option."
}

View File

@@ -5,7 +5,6 @@
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import {
@@ -15,51 +14,55 @@ import {
Resource,
Tenant
} from 'azurecore';
import { Deferred } from '../interfaces';
import * as url from 'url';
import { SimpleTokenCache } from '../simpleTokenCache';
import * as Constants from '../../constants';
import { SimpleTokenCache } from '../utils/simpleTokenCache';
import { MemoryDatabase } from '../utils/memoryDatabase';
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { Logger } from '../../utils/Logger';
import * as qs from 'qs';
import { AzureAuthError } from './azureAuthError';
import { AccountInfo, AuthenticationResult, InteractionRequiredAuthError, PublicClientApplication } from '@azure/msal-node';
const localize = nls.loadMessageBundle();
export abstract class AzureAuth implements vscode.Disposable {
public static ACCOUNT_VERSION = '2.0';
protected readonly memdb = new MemoryDatabase<string>();
protected readonly WorkSchoolAccountType: string = 'work_school';
protected readonly MicrosoftAccountType: string = 'microsoft';
protected readonly loginEndpointUrl: string;
public readonly commonTenant: Tenant;
public readonly organizationTenant: Tenant;
protected readonly redirectUri: string;
protected readonly scopes: string[];
protected readonly scopesString: string;
protected readonly clientId: string;
protected readonly resources: Resource[];
private _authLibrary: string | undefined;
constructor(
protected readonly metadata: AzureAccountProviderMetadata,
protected readonly tokenCache: SimpleTokenCache,
protected readonly context: vscode.ExtensionContext,
protected clientApplication: PublicClientApplication,
protected readonly uriEventEmitter: vscode.EventEmitter<vscode.Uri>,
protected readonly authType: AzureAuthType,
public readonly userFriendlyName: string
public readonly userFriendlyName: string,
public readonly authLibrary: string
) {
this._authLibrary = authLibrary;
this.loginEndpointUrl = this.metadata.settings.host;
this.commonTenant = {
id: 'common',
displayName: 'common',
};
this.organizationTenant = {
id: 'organizations',
displayName: 'organizations',
};
this.redirectUri = this.metadata.settings.redirectUri;
this.clientId = this.metadata.settings.clientId;
this.resources = [
this.metadata.settings.armResource,
this.metadata.settings.graphResource,
@@ -100,19 +103,39 @@ export abstract class AzureAuth implements vscode.Disposable {
if (!this.metadata.settings.microsoftResource) {
throw new Error(localize('noMicrosoftResource', "Provider '{0}' does not have a Microsoft resource endpoint defined.", this.metadata.displayName));
}
const result = await this.login(this.commonTenant, this.metadata.settings.microsoftResource);
loginComplete = result.authComplete;
if (!result?.response) {
Logger.error('Authentication failed');
return {
canceled: false
if (this._authLibrary === Constants.AuthLibrary.MSAL) {
const result = await this.loginMsal(this.organizationTenant, this.metadata.settings.microsoftResource);
loginComplete = result.authComplete;
if (!result?.response || !result.response?.account) {
Logger.error(`Authentication failed: ${loginComplete}`);
return {
canceled: false
};
}
const token: Token = {
token: result.response.accessToken,
key: result.response.account.homeAccountId,
tokenType: result.response.tokenType
};
const tokenClaims = <TokenClaims>result.response.idTokenClaims;
const account = await this.hydrateAccount(token, tokenClaims);
loginComplete?.resolve();
return account;
} else {// fallback to ADAL as default
const result = await this.loginAdal(this.commonTenant, this.metadata.settings.microsoftResource);
loginComplete = result.authComplete;
if (!result?.response) {
Logger.error('Authentication failed - no response');
return {
canceled: false
};
}
const account = await this.hydrateAccount(result.response.accessToken, result.response.tokenClaims);
loginComplete?.resolve();
return account;
}
const account = await this.hydrateAccount(result.response.accessToken, result.response.tokenClaims);
loginComplete?.resolve();
return account;
} catch (ex) {
Logger.error('Login failed');
Logger.error(`Login failed: ${ex}`);
if (ex instanceof AzureAuthError) {
if (loginComplete) {
loginComplete.reject(ex);
@@ -122,20 +145,27 @@ export abstract class AzureAuth implements vscode.Disposable {
Logger.error(ex.originalMessageAndException);
}
} else {
const message = ex.errorMessage || ex.message;
if (message) {
loginComplete?.reject(new AzureAuthError(message, message, undefined));
return {
canceled: false,
errorCode: ex.errorCode,
errorMessage: message
};
}
Logger.error(ex);
}
return {
canceled: false
};
} finally {
loginComplete?.reject(new AzureAuthError(localize('azureAuth.unidentifiedError', "Unidentified error with azure authentication"), 'Unidentified error with azure auth', undefined));
}
}
public async refreshAccess(account: AzureAccount): Promise<AzureAccount> {
public async refreshAccessAdal(account: AzureAccount): Promise<AzureAccount> {
// Deprecated account - delete it.
if (account.key.accountVersion !== AzureAuth.ACCOUNT_VERSION) {
if (account.key.accountVersion !== Constants.AccountVersion) {
account.delete = true;
return account;
}
@@ -144,7 +174,7 @@ export abstract class AzureAuth implements vscode.Disposable {
// We want to return the one that owns the Azure account.
// Not doing so can result in token being issued for the wrong tenant
const tenant = account.properties.owningTenant;
const tokenResult = await this.getAccountSecurityToken(account, tenant.id, azdata.AzureResource.MicrosoftResourceManagement);
const tokenResult = await this.getAccountSecurityTokenAdal(account, tenant.id, azdata.AzureResource.MicrosoftResourceManagement);
if (!tokenResult) {
account.isStale = true;
return account;
@@ -154,32 +184,37 @@ export abstract class AzureAuth implements vscode.Disposable {
} catch (ex) {
if (ex instanceof AzureAuthError) {
void vscode.window.showErrorMessage(ex.message);
Logger.error(ex.originalMessageAndException);
Logger.error(`Error refreshing access for account ${account.displayInfo.displayName}`, ex.originalMessageAndException);
} else {
Logger.error(ex);
}
Logger.error(ex);
account.isStale = true;
return account;
}
}
public async hydrateAccount(token: Token | AccessToken, tokenClaims: TokenClaims): Promise<AzureAccount> {
const tenants = await this.getTenants({ ...token });
const account = this.createAccount(tokenClaims, token.key, tenants);
let account: azdata.Account;
if (this._authLibrary === Constants.AuthLibrary.MSAL) {
const tenants = await this.getTenantsMsal(token.token);
account = this.createAccount(tokenClaims, token.key, tenants);
} else { // fallback to ADAL as default
const tenants = await this.getTenantsAdal({ ...token });
account = this.createAccount(tokenClaims, token.key, tenants);
}
return account;
}
public async getAccountSecurityToken(account: AzureAccount, tenantId: string, azureResource: azdata.AzureResource): Promise<Token | undefined> {
public async getAccountSecurityTokenAdal(account: AzureAccount, tenantId: string, azureResource: azdata.AzureResource): Promise<Token | undefined> {
if (account.isStale === true) {
Logger.error('Account was stale. No tokens being fetched.');
return undefined;
}
const resource = this.resources.find(s => s.azureResourceId === azureResource);
if (!resource) {
Logger.error('Invalid resource, not fetching', azureResource);
if (!resource) {
Logger.error(`Unable to find Azure resource ${azureResource}`);
return undefined;
}
@@ -196,7 +231,7 @@ export abstract class AzureAuth implements vscode.Disposable {
throw new AzureAuthError(localize('azure.tenantNotFound', "Specified tenant with ID '{0}' not found.", tenantId), `Tenant ${tenantId} not found.`, undefined);
}
const cachedTokens = await this.getSavedToken(tenant, resource, account.key);
const cachedTokens = await this.getSavedTokenAdal(tenant, resource, account.key);
// Let's check to see if we can just use the cached tokens to return to the user
if (cachedTokens?.accessToken) {
@@ -213,7 +248,7 @@ export abstract class AzureAuth implements vscode.Disposable {
const maxTolerance = 2 * 60; // two minutes
if (remainingTime < maxTolerance) {
const result = await this.refreshToken(tenant, resource, cachedTokens.refreshToken);
const result = await this.refreshTokenAdal(tenant, resource, cachedTokens.refreshToken);
if (result) {
accessToken = result.accessToken;
expiresOn = Number(result.expiresOn);
@@ -224,7 +259,7 @@ export abstract class AzureAuth implements vscode.Disposable {
return {
...accessToken,
expiresOn: expiresOn,
tokenType: 'Bearer'
tokenType: Constants.Bearer
};
}
}
@@ -234,7 +269,7 @@ export abstract class AzureAuth implements vscode.Disposable {
if (!this.metadata.settings.microsoftResource) {
throw new Error(localize('noMicrosoftResource', "Provider '{0}' does not have a Microsoft resource endpoint defined.", this.metadata.displayName));
}
const baseTokens = await this.getSavedToken(this.commonTenant, this.metadata.settings.microsoftResource, account.key);
const baseTokens = await this.getSavedTokenAdal(this.commonTenant, this.metadata.settings.microsoftResource, account.key);
if (!baseTokens) {
Logger.error('User had no base tokens for the basic resource registered. This should not happen and indicates something went wrong with the authentication cycle');
const msg = localize('azure.noBaseToken', 'Something failed with the authentication, or your tokens have been deleted from the system. Please try adding your account to Azure Data Studio again.');
@@ -242,20 +277,20 @@ export abstract class AzureAuth implements vscode.Disposable {
throw new AzureAuthError(msg, 'No base token found', undefined);
}
// Let's try to convert the access token type, worst case we'll have to prompt the user to do an interactive authentication.
const result = await this.refreshToken(tenant, resource, baseTokens.refreshToken);
const result = await this.refreshTokenAdal(tenant, resource, baseTokens.refreshToken);
if (result?.accessToken) {
return {
...result.accessToken,
expiresOn: Number(result.expiresOn),
tokenType: 'Bearer'
tokenType: Constants.Bearer
};
}
return undefined;
}
protected abstract loginAdal(tenant: Tenant, resource: Resource): Promise<{ response: OAuthTokenResponse | undefined, authComplete: Deferred<void, Error> }>;
protected abstract login(tenant: Tenant, resource: Resource): Promise<{ response: OAuthTokenResponse | undefined, authComplete: Deferred<void, Error> }>;
protected abstract loginMsal(tenant: Tenant, resource: Resource): Promise<{ response: AuthenticationResult | null, authComplete: Deferred<void, Error> }>;
/**
* Refreshes a token, if a refreshToken is passed in then we use that. If it is not passed in then we will prompt the user for consent.
@@ -265,8 +300,8 @@ export abstract class AzureAuth implements vscode.Disposable {
* @returns The oauth token response or undefined. Undefined is returned when the user wants to ignore a tenant or chooses not to start the
* re-authentication process for their tenant.
*/
public async refreshToken(tenant: Tenant, resource: Resource, refreshToken: RefreshToken | undefined): Promise<OAuthTokenResponse | undefined> {
Logger.pii('Refreshing token', [{ name: 'token', objOrArray: refreshToken }], []);
public async refreshTokenAdal(tenant: Tenant, resource: Resource, refreshToken: RefreshToken | undefined): Promise<OAuthTokenResponse | undefined> {
Logger.piiSanitized('Refreshing token', [{ name: 'token', objOrArray: refreshToken }], []);
if (refreshToken) {
const postData: RefreshTokenPostData = {
grant_type: 'refresh_token',
@@ -275,36 +310,113 @@ export abstract class AzureAuth implements vscode.Disposable {
tenant: tenant.id,
resource: resource.endpoint
};
return this.getToken(tenant, resource, postData);
return this.getTokenAdal(tenant, resource, postData);
}
return this.handleInteractionRequired(tenant, resource);
return this.handleInteractionRequiredAdal(tenant, resource);
}
public async getToken(tenant: Tenant, resource: Resource, postData: AuthorizationCodePostData | TokenPostData | RefreshTokenPostData): Promise<OAuthTokenResponse | undefined> {
Logger.verbose('Fetching token');
/**
* Gets the access token for the correct account and scope from the token cache, if the correct token doesn't exist in the token cache
* (i.e. expired token, wrong scope, etc.), sends a request for a new token using the refresh token
* @param accountId
* @param azureResource
* @returns The authentication result, including the access token
*/
public async getTokenMsal(accountId: string, azureResource: azdata.AzureResource, tenantId: string): Promise<AuthenticationResult | azdata.PromptFailedResult | null> {
const resource = this.resources.find(s => s.azureResourceId === azureResource);
if (!resource) {
Logger.error(`Unable to find Azure resource ${azureResource}`);
return null;
}
// Resource endpoint must end with '/' to form a valid scope for MSAL token request.
const endpoint = resource.endpoint.endsWith('/') ? resource.endpoint : resource.endpoint + '/';
let account: AccountInfo | null = await this.getAccountFromMsalCache(accountId);
if (!account) {
Logger.error('Error: Could not fetch account when acquiring token');
return null;
}
let newScope;
if (resource.azureResourceId === azdata.AzureResource.ResourceManagement) {
newScope = [`${endpoint}user_impersonation`];
} else {
newScope = [`${endpoint}.default`];
}
// construct request
// forceRefresh needs to be set true here in order to fetch the correct token, due to this issue
// https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/3687
const tokenRequest = {
account: account,
authority: `${this.loginEndpointUrl}${tenantId}`,
scopes: newScope,
forceRefresh: true
};
try {
return await this.clientApplication.acquireTokenSilent(tokenRequest);
} catch (e) {
Logger.error('Failed to acquireTokenSilent', e);
if (e instanceof InteractionRequiredAuthError) {
// build refresh token request
const tenant: Tenant = {
id: tenantId,
displayName: ''
};
return this.handleInteractionRequiredMsal(tenant, resource);
} else {
if (e.name === 'ClientAuthError') {
Logger.verbose('[ClientAuthError] Failed to silently acquire token');
}
return {
canceled: false,
name: e.name,
errorCode: e.errorCode,
errorMessage: e.errorMessage || e.message
}
}
}
}
public async getAccountFromMsalCache(accountId: string): Promise<AccountInfo | null> {
const cache = this.clientApplication.getTokenCache();
if (!cache) {
Logger.error('Error: Could not fetch token cache.');
return null;
}
let account: AccountInfo | null = null;
// if the accountId is a home ID, it will include a "." character
if (accountId.includes(".")) {
account = await cache.getAccountByHomeId(accountId);
} else {
account = await cache.getAccountByLocalId(accountId);
}
return account;
}
public async getTokenAdal(tenant: Tenant, resource: Resource, postData: AuthorizationCodePostData | TokenPostData | RefreshTokenPostData): Promise<OAuthTokenResponse | undefined> {
Logger.verbose('Fetching token for tenant {0}', tenant.id);
const tokenUrl = `${this.loginEndpointUrl}${tenant.id}/oauth2/token`;
const response = await this.makePostRequest(tokenUrl, postData);
Logger.pii('Token: ', [{ name: 'access token', objOrArray: response.data }, { name: 'refresh token', objOrArray: response.data }],
[{ name: 'access token', value: response.data.access_token }, { name: 'refresh token', value: response.data.refresh_token }]);
if (response.data.error === 'interaction_required') {
return this.handleInteractionRequired(tenant, resource);
}
Logger.piiSanitized('Token: ', [{ name: 'access token', objOrArray: response.data }, { name: 'refresh token', objOrArray: response.data }], []);
if (response.data.error === 'interaction_required') {
return this.handleInteractionRequiredAdal(tenant, resource);
}
if (response.data.error) {
Logger.error('Response error!', response.data);
Logger.error(`Response returned error : ${response.data}`);
throw new AzureAuthError(localize('azure.responseError', "Token retrieval failed with an error. [Open developer tools]({0}) for more details.", 'command:workbench.action.toggleDevTools'), 'Token retrieval failed', undefined);
}
const accessTokenString = response.data.access_token;
const refreshTokenString = response.data.refresh_token;
const expiresOnString = response.data.expires_on;
return this.getTokenHelper(tenant, resource, accessTokenString, refreshTokenString, expiresOnString);
return this.getTokenHelperAdal(tenant, resource, accessTokenString, refreshTokenString, expiresOnString);
}
public async getTokenHelper(tenant: Tenant, resource: Resource, accessTokenString: string, refreshTokenString: string, expiresOnString: string): Promise<OAuthTokenResponse> {
public async getTokenHelperAdal(tenant: Tenant, resource: Resource, accessTokenString: string, refreshTokenString: string, expiresOnString: string): Promise<OAuthTokenResponse> {
if (!accessTokenString) {
const msg = localize('azure.accessTokenEmpty', 'No access token returned from Microsoft OAuth');
throw new AzureAuthError(msg, 'Access token was empty', undefined);
@@ -349,28 +461,57 @@ export abstract class AzureAuth implements vscode.Disposable {
const accountKey: azdata.AccountKey = {
providerId: this.metadata.id,
accountId: userKey
accountId: userKey,
authLibrary: this._authLibrary
};
await this.saveToken(tenant, resource, accountKey, result);
await this.saveTokenAdal(tenant, resource, accountKey, result);
return result;
}
public async getTenantsMsal(token: string): Promise<Tenant[]> {
const tenantUri = url.resolve(this.metadata.settings.armResource.endpoint, 'tenants?api-version=2019-11-01');
try {
Logger.verbose('Fetching tenants with uri {0}', tenantUri);
let tenantList: string[] = [];
const tenantResponse = await this.makeGetRequest(tenantUri, token);
const tenants: Tenant[] = tenantResponse.data.value.map((tenantInfo: TenantResponse) => {
if (tenantInfo.displayName) {
tenantList.push(tenantInfo.displayName);
} else {
tenantList.push(tenantInfo.tenantId);
Logger.info('Tenant display name found empty: {0}', tenantInfo.tenantId);
}
return {
id: tenantInfo.tenantId,
displayName: tenantInfo.displayName ? tenantInfo.displayName : tenantInfo.tenantId,
userId: token,
tenantCategory: tenantInfo.tenantCategory
} as Tenant;
});
Logger.verbose(`Tenants: ${tenantList}`);
const homeTenantIndex = tenants.findIndex(tenant => tenant.tenantCategory === Constants.HomeCategory);
// remove home tenant from list of tenants
if (homeTenantIndex >= 0) {
const homeTenant = tenants.splice(homeTenantIndex, 1);
tenants.unshift(homeTenant[0]);
}
Logger.verbose(`Filtered Tenants: ${tenantList}`);
return tenants;
} catch (ex) {
Logger.error(`Error fetching tenants :${ex}`);
throw new Error('Error retrieving tenant information');
}
}
//#region tenant calls
public async getTenants(token: AccessToken): Promise<Tenant[]> {
interface TenantResponse { // https://docs.microsoft.com/en-us/rest/api/resources/tenants/list
id: string
tenantId: string
displayName?: string
tenantCategory?: string
}
public async getTenantsAdal(token: AccessToken): Promise<Tenant[]> {
const tenantUri = url.resolve(this.metadata.settings.armResource.endpoint, 'tenants?api-version=2019-11-01');
try {
Logger.verbose('Fetching tenants', tenantUri);
Logger.verbose('Fetching tenants with URI: {0}', tenantUri);
let tenantList: string[] = [];
const tenantResponse = await this.makeGetRequest(tenantUri, token.token);
if (tenantResponse.status !== 200) {
Logger.error(`Error with tenant response, status: ${tenantResponse.status} | status text: ${tenantResponse.statusText}`);
@@ -378,16 +519,22 @@ export abstract class AzureAuth implements vscode.Disposable {
throw new Error('Error with tenant response');
}
const tenants: Tenant[] = tenantResponse.data.value.map((tenantInfo: TenantResponse) => {
Logger.verbose(`Tenant: ${tenantInfo.displayName}`);
if (tenantInfo.displayName) {
tenantList.push(tenantInfo.displayName);
} else {
tenantList.push(tenantInfo.tenantId);
Logger.info('Tenant display name found empty: {0}', tenantInfo.tenantId);
}
return {
id: tenantInfo.tenantId,
displayName: tenantInfo.displayName ? tenantInfo.displayName : localize('azureWorkAccountDisplayName', "Work or school account"),
displayName: tenantInfo.displayName ? tenantInfo.displayName : tenantInfo.tenantId,
userId: token.key,
tenantCategory: tenantInfo.tenantCategory
} as Tenant;
});
const homeTenantIndex = tenants.findIndex(tenant => tenant.tenantCategory === 'Home');
Logger.verbose(`Tenants: ${tenantList}`);
const homeTenantIndex = tenants.findIndex(tenant => tenant.tenantCategory === Constants.HomeCategory);
// remove home tenant from list of tenants
if (homeTenantIndex >= 0) {
const homeTenant = tenants.splice(homeTenantIndex, 1);
tenants.unshift(homeTenant[0]);
@@ -403,16 +550,16 @@ export abstract class AzureAuth implements vscode.Disposable {
//#endregion
//#region token management
private async saveToken(tenant: Tenant, resource: Resource, accountKey: azdata.AccountKey, { accessToken, refreshToken, expiresOn }: OAuthTokenResponse) {
private async saveTokenAdal(tenant: Tenant, resource: Resource, accountKey: azdata.AccountKey, { accessToken, refreshToken, expiresOn }: OAuthTokenResponse) {
const msg = localize('azure.cacheErrorAdd', "Error when adding your account to the cache.");
if (!tenant.id || !resource.id) {
Logger.pii('Tenant ID or resource ID was undefined', [], [], tenant, resource);
Logger.piiSanitized('Tenant ID or resource ID was undefined', [], [], tenant, resource);
throw new AzureAuthError(msg, 'Adding account to cache failed', undefined);
}
try {
Logger.pii(`Saving access token`, [{ name: 'access_token', objOrArray: accessToken }], []);
Logger.piiSanitized(`Saving access token`, [{ name: 'access_token', objOrArray: accessToken }], []);
await this.tokenCache.saveCredential(`${accountKey.accountId}_access_${resource.id}_${tenant.id}`, JSON.stringify(accessToken));
Logger.pii(`Saving refresh token`, [{ name: 'refresh_token', objOrArray: refreshToken }], []);
Logger.piiSanitized(`Saving refresh token`, [{ name: 'refresh_token', objOrArray: refreshToken }], []);
await this.tokenCache.saveCredential(`${accountKey.accountId}_refresh_${resource.id}_${tenant.id}`, JSON.stringify(refreshToken));
this.memdb.set(`${accountKey.accountId}_${tenant.id}_${resource.id}`, expiresOn);
} catch (ex) {
@@ -421,12 +568,12 @@ export abstract class AzureAuth implements vscode.Disposable {
}
}
public async getSavedToken(tenant: Tenant, resource: Resource, accountKey: azdata.AccountKey): Promise<{ accessToken: AccessToken, refreshToken: RefreshToken | undefined, expiresOn: string } | undefined> {
public async getSavedTokenAdal(tenant: Tenant, resource: Resource, accountKey: azdata.AccountKey): Promise<{ accessToken: AccessToken, refreshToken: RefreshToken | undefined, expiresOn: string } | undefined> {
const getMsg = localize('azure.cacheErrorGet', "Error when getting your account from the cache");
const parseMsg = localize('azure.cacheErrorParse', "Error when parsing your account from the cache");
if (!tenant.id || !resource.id) {
Logger.pii('Tenant ID or resource ID was undefined', [], [], tenant, resource);
Logger.piiSanitized('Tenant ID or resource ID was undefined', [], [], tenant, resource);
throw new AzureAuthError(getMsg, 'Getting account from cache failed', undefined);
}
@@ -453,7 +600,7 @@ export abstract class AzureAuth implements vscode.Disposable {
if (refreshTokenString) {
refreshToken = JSON.parse(refreshTokenString);
}
Logger.pii('GetSavedToken ', [{ name: 'access', objOrArray: accessToken }, { name: 'refresh', objOrArray: refreshToken }], [], `expiresOn=${expiresOn}`);
Logger.piiSanitized('GetSavedToken ', [{ name: 'access', objOrArray: accessToken }, { name: 'refresh', objOrArray: refreshToken }], [], `expiresOn=${expiresOn}`);
return {
accessToken, refreshToken, expiresOn
};
@@ -464,12 +611,22 @@ export abstract class AzureAuth implements vscode.Disposable {
}
//#endregion
//#region interaction handling
public async handleInteractionRequired(tenant: Tenant, resource: Resource): Promise<OAuthTokenResponse | undefined> {
//#region interaction handling
public async handleInteractionRequiredMsal(tenant: Tenant, resource: Resource): Promise<AuthenticationResult | null> {
const shouldOpen = await this.askUserForInteraction(tenant, resource);
if (shouldOpen) {
const result = await this.login(tenant, resource);
const result = await this.loginMsal(tenant, resource);
result?.authComplete?.resolve();
return result?.response;
}
return null;
}
public async handleInteractionRequiredAdal(tenant: Tenant, resource: Resource): Promise<OAuthTokenResponse | undefined> {
const shouldOpen = await this.askUserForInteraction(tenant, resource);
if (shouldOpen) {
const result = await this.loginAdal(tenant, resource);
result?.authComplete?.resolve();
return result?.response;
}
@@ -487,13 +644,14 @@ export abstract class AzureAuth implements vscode.Disposable {
}
const getTenantConfigurationSet = (): Set<string> => {
const configuration = vscode.workspace.getConfiguration('azure.tenant.config');
const configuration = vscode.workspace.getConfiguration(Constants.AzureTenantConfigSection);
let values: string[] = configuration.get('filter') ?? [];
return new Set<string>(values);
};
// The user wants to ignore this tenant.
if (getTenantConfigurationSet().has(tenant.id)) {
Logger.info(`Tenant ${tenant.id} found in the ignore list, authentication will not be attempted.`);
return false;
}
@@ -528,7 +686,7 @@ export abstract class AzureAuth implements vscode.Disposable {
}
};
const messageBody = localize('azurecore.consentDialog.body', "Your tenant '{0} ({1})' requires you to re-authenticate again to access {2} resources. Press Open to start the authentication process.", tenant.displayName, tenant.id, resource.id);
const messageBody = localize('azurecore.consentDialog.body', "Your tenant '{0} ({1})' requires you to re-authenticate again to access {2} resources. Press Open to start the authentication process.", tenant.displayName, tenant.id, resource.endpoint);
const result = await vscode.window.showInformationMessage(messageBody, { modal: true }, openItem, closeItem, dontAskAgainItem);
if (result?.action) {
@@ -542,28 +700,33 @@ export abstract class AzureAuth implements vscode.Disposable {
//#region data modeling
public createAccount(tokenClaims: TokenClaims, key: string, tenants: Tenant[]): AzureAccount {
Logger.verbose(`Token Claims: ${tokenClaims.name}`);
Logger.verbose(`Token Claims acccount: ${tokenClaims.name}, TID: ${tokenClaims.tid}`);
tenants.forEach((tenant) => {
Logger.verbose(
`Tenant ID: ${tenant.id}
Tenant Name: ${tenant.displayName}`);
Logger.verbose(`Tenant ID: ${tenant.id}, Tenant Name: ${tenant.displayName}`);
});
// Determine if this is a microsoft account
let accountIssuer = 'unknown';
if (tokenClaims.iss === 'https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/') {
accountIssuer = 'corp';
if (tokenClaims.iss === 'https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/' ||
tokenClaims.iss === `${this.loginEndpointUrl}72f988bf-86f1-41af-91ab-2d7cd011db47/v2.0`) {
accountIssuer = Constants.AccountIssuer.Corp;
}
if (tokenClaims?.idp === 'live.com') {
accountIssuer = 'msft';
accountIssuer = Constants.AccountIssuer.Msft;
}
const name = tokenClaims.name ?? tokenClaims.email ?? tokenClaims.unique_name;
const email = tokenClaims.email ?? tokenClaims.unique_name;
const name = tokenClaims.name ?? tokenClaims.email ?? tokenClaims.unique_name ?? tokenClaims.preferred_username;
const email = tokenClaims.email ?? tokenClaims.unique_name ?? tokenClaims.preferred_username;
let owningTenant: Tenant = this.commonTenant; // default to common tenant
// Read more about tid > https://learn.microsoft.com/azure/active-directory/develop/id-tokens
const owningTenant = tenants.find(t => t.id === tokenClaims.tid)
?? { 'id': tokenClaims.tid, 'displayName': 'Microsoft Account' };
if (tokenClaims.tid) {
owningTenant = tenants.find(t => t.id === tokenClaims.tid) ?? { 'id': tokenClaims.tid, 'displayName': 'Microsoft Account' };
} else {
Logger.info('Could not find tenant information from tokenClaims, falling back to common Tenant.');
}
let displayName = name;
if (email) {
@@ -572,25 +735,26 @@ export abstract class AzureAuth implements vscode.Disposable {
let contextualDisplayName: string;
switch (accountIssuer) {
case 'corp':
case Constants.AccountIssuer.Corp:
contextualDisplayName = localize('azure.microsoftCorpAccount', "Microsoft Corp");
break;
case 'msft':
case Constants.AccountIssuer.Msft:
contextualDisplayName = localize('azure.microsoftAccountDisplayName', 'Microsoft Account');
break;
default:
contextualDisplayName = displayName;
}
let accountType = accountIssuer === 'msft'
? this.MicrosoftAccountType
: this.WorkSchoolAccountType;
let accountType = accountIssuer === Constants.AccountIssuer.Msft
? Constants.AccountType.Microsoft
: Constants.AccountType.WorkSchool;
const account = {
key: {
providerId: this.metadata.id,
accountId: key,
accountVersion: AzureAuth.ACCOUNT_VERSION,
accountVersion: Constants.AccountVersion,
authLibrary: this._authLibrary
},
name: displayName,
displayInfo: {
@@ -603,7 +767,7 @@ export abstract class AzureAuth implements vscode.Disposable {
},
properties: {
providerSettings: this.metadata,
isMsAccount: accountIssuer === 'msft',
isMsAccount: accountIssuer === Constants.AccountIssuer.Msft,
owningTenant: owningTenant,
tenants,
azureAuthType: this.authType
@@ -627,7 +791,7 @@ export abstract class AzureAuth implements vscode.Disposable {
// Intercept response and print out the response for future debugging
const response = await axios.post(url, qs.stringify(postData), config);
Logger.pii('POST request ', [{ name: 'data', objOrArray: postData }, { name: 'response', objOrArray: response.data }], [], url);
Logger.piiSanitized('POST request ', [{ name: 'data', objOrArray: postData }, { name: 'response', objOrArray: response.data }], [], url);
return response;
}
@@ -641,7 +805,7 @@ export abstract class AzureAuth implements vscode.Disposable {
};
const response = await axios.get(url, config);
Logger.pii('GET request ', [{ name: 'response', objOrArray: response.data.value ?? response.data }], [], url,);
Logger.piiSanitized('GET request ', [{ name: 'response', objOrArray: response.data.value ?? response.data }], [], url,);
return response;
}
@@ -660,8 +824,10 @@ export abstract class AzureAuth implements vscode.Disposable {
protected toBase64UrlEncoding(base64string: string): string {
return base64string.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); // Need to use base64url encoding
}
public async deleteAllCache(): Promise<void> {
public async deleteAllCacheMsal(): Promise<void> {
this.clientApplication.clearCache();
}
public async deleteAllCacheAdal(): Promise<void> {
const results = await this.tokenCache.findCredentials('');
for (let { account } of results) {
@@ -671,17 +837,34 @@ export abstract class AzureAuth implements vscode.Disposable {
public async clearCredentials(account: azdata.AccountKey): Promise<void> {
try {
return this.deleteAccountCache(account);
// remove account based on authLibrary field, accounts added before this field was present will default to
// ADAL method of account removal
if (account.authLibrary === Constants.AuthLibrary.MSAL) {
return await this.deleteAccountCacheMsal(account);
} else { // fallback to ADAL by default
return await this.deleteAccountCacheAdal(account);
}
} catch (ex) {
const msg = localize('azure.cacheErrrorRemove', "Error when removing your account from the cache.");
void vscode.window.showErrorMessage(msg);
Logger.error('Error when removing tokens.', ex);
// We need not prompt user for error if token could not be removed from cache.
Logger.error('Error when removing token from cache: ', ex);
}
}
public async deleteAccountCache(account: azdata.AccountKey): Promise<void> {
const results = await this.tokenCache.findCredentials(account.accountId);
public async deleteAccountCacheMsal(account: azdata.AccountKey): Promise<void> {
const tokenCache = this.clientApplication.getTokenCache();
let msalAccount: AccountInfo | null = await this.getAccountFromMsalCache(account.accountId);
if (!msalAccount) {
Logger.error(`MSAL: Unable to find account ${account.accountId} for removal`);
throw Error(`Unable to find account ${account.accountId}`);
}
await tokenCache.removeAccount(msalAccount);
}
public async deleteAccountCacheAdal(account: azdata.AccountKey): Promise<void> {
const results = await this.tokenCache.findCredentials(account.accountId);
if (!results) {
Logger.error('ADAL: Unable to find account for removal');
}
for (let { account } of results) {
await this.tokenCache.clearCredential(account);
}
@@ -722,6 +905,13 @@ export interface RefreshToken extends AccountKey {
key: string
}
export interface TenantResponse { // https://docs.microsoft.com/en-us/rest/api/resources/tenants/list
id: string
tenantId: string
displayName?: string
tenantCategory?: string
}
export interface MultiTenantTokenResponse {
[tenantId: string]: Token | undefined;
}

View File

@@ -8,15 +8,17 @@ import { AzureAccountProviderMetadata, AzureAuthType, Resource, Tenant } from 'a
import { Deferred } from '../interfaces';
import * as vscode from 'vscode';
import * as crypto from 'crypto';
import { SimpleTokenCache } from '../simpleTokenCache';
import { SimpleTokenCache } from '../utils/simpleTokenCache';
import { SimpleWebServer } from '../utils/simpleWebServer';
import { AzureAuthError } from './azureAuthError';
import { Logger } from '../../utils/Logger';
import * as Constants from '../../constants';
import * as nls from 'vscode-nls';
import * as path from 'path';
import * as http from 'http';
import * as qs from 'qs';
import { promises as fs } from 'fs';
import { PublicClientApplication, CryptoProvider, AuthorizationUrlRequest, AuthorizationCodeRequest, AuthenticationResult } from '@azure/msal-node';
const localize = nls.loadMessageBundle();
@@ -28,33 +30,43 @@ interface AuthCodeResponse {
interface CryptoValues {
nonce: string;
challengeMethod: string;
codeVerifier: string;
codeChallenge: string;
}
export class AzureAuthCodeGrant extends AzureAuth {
private static readonly USER_FRIENDLY_NAME: string = localize('azure.azureAuthCodeGrantName', 'Azure Auth Code Grant');
private cryptoProvider: CryptoProvider;
private pkceCodes: CryptoValues;
constructor(
metadata: AzureAccountProviderMetadata,
tokenCache: SimpleTokenCache,
context: vscode.ExtensionContext,
uriEventEmitter: vscode.EventEmitter<vscode.Uri>,
clientApplication: PublicClientApplication,
authLibrary: string
) {
super(metadata, tokenCache, context, uriEventEmitter, AzureAuthType.AuthCodeGrant, AzureAuthCodeGrant.USER_FRIENDLY_NAME);
super(metadata, tokenCache, context, clientApplication, uriEventEmitter, AzureAuthType.AuthCodeGrant, AzureAuthCodeGrant.USER_FRIENDLY_NAME, authLibrary);
this.cryptoProvider = new CryptoProvider();
this.pkceCodes = {
nonce: '',
challengeMethod: Constants.S256_CODE_CHALLENGE_METHOD, // Use SHA256 as the challenge method
codeVerifier: '', // Generate a code verifier for the Auth Code Request first
codeChallenge: '', // Generate a code challenge from the previously generated code verifier
};
}
protected async login(tenant: Tenant, resource: Resource): Promise<{ response: OAuthTokenResponse | undefined, authComplete: Deferred<void, Error> }> {
protected async loginAdal(tenant: Tenant, resource: Resource): Promise<{ response: OAuthTokenResponse | undefined, authComplete: Deferred<void, Error> }> {
let authCompleteDeferred: Deferred<void, Error>;
let authCompletePromise = new Promise<void>((resolve, reject) => authCompleteDeferred = { resolve, reject });
let authResponse: AuthCodeResponse;
if (vscode.env.uiKind === vscode.UIKind.Web) {
authResponse = await this.loginWeb(tenant, resource);
authResponse = await this.loginWebAdal(tenant, resource);
} else {
authResponse = await this.loginDesktop(tenant, resource, authCompletePromise);
authResponse = await this.loginDesktopAdal(tenant, resource, authCompletePromise);
}
return {
@@ -63,6 +75,30 @@ export class AzureAuthCodeGrant extends AzureAuth {
};
}
protected async loginMsal(tenant: Tenant, resource: Resource): Promise<{ response: AuthenticationResult | null, authComplete: Deferred<void, Error> }> {
let authCompleteDeferred: Deferred<void, Error>;
let authCompletePromise = new Promise<void>((resolve, reject) => authCompleteDeferred = { resolve, reject });
let authCodeRequest: AuthorizationCodeRequest;
if (vscode.env.uiKind === vscode.UIKind.Web) {
authCodeRequest = await this.loginWebMsal(tenant, resource);
} else {
authCodeRequest = await this.loginDesktopMsal(tenant, resource, authCompletePromise);
}
let result = await this.clientApplication.acquireTokenByCode(authCodeRequest);
if (!result) {
Logger.error('Failed to acquireTokenByCode');
Logger.error(`Auth Code Request: ${JSON.stringify(authCodeRequest)}`)
throw Error('Failed to fetch token using auth code');
} else {
return {
response: result,
authComplete: authCompleteDeferred!
};
}
}
/**
* Requests an OAuthTokenResponse from Microsoft OAuth
*
@@ -79,12 +115,47 @@ export class AzureAuthCodeGrant extends AzureAuth {
resource: resource.endpoint
};
return this.getToken(tenant, resource, postData);
return this.getTokenAdal(tenant, resource, postData);
}
private async loginWeb(tenant: Tenant, resource: Resource): Promise<AuthCodeResponse> {
private async loginWebMsal(tenant: Tenant, resource: Resource): Promise<AuthorizationCodeRequest> {
const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://microsoft.azurecore`));
const { nonce, codeVerifier, codeChallenge } = this.createCryptoValues();
await this.createCryptoValuesMsal();
const port = (callbackUri.authority.match(/:([0-9]*)$/) || [])[1] || (callbackUri.scheme === 'https' ? 443 : 80);
const state = `${port},${encodeURIComponent(this.pkceCodes.nonce)},${encodeURIComponent(callbackUri.query)}`;
try {
let authUrlRequest: AuthorizationUrlRequest;
authUrlRequest = {
scopes: this.scopes,
redirectUri: this.redirectUri,
codeChallenge: this.pkceCodes.codeChallenge,
codeChallengeMethod: this.pkceCodes.challengeMethod,
prompt: Constants.SELECT_ACCOUNT,
state: state
};
let authCodeRequest: AuthorizationCodeRequest;
authCodeRequest = {
scopes: this.scopes,
redirectUri: this.redirectUri,
codeVerifier: this.pkceCodes.codeVerifier,
code: ''
};
let authCodeUrl = await this.clientApplication.getAuthCodeUrl(authUrlRequest);
await vscode.env.openExternal(vscode.Uri.parse(authCodeUrl));
const authCode = await this.handleWebResponse(state);
authCodeRequest.code = authCode;
return authCodeRequest;
} catch (e) {
Logger.error('MSAL: Error requesting auth code', e);
throw new AzureAuthError('error', 'Error requesting auth code', e);
}
}
private async loginWebAdal(tenant: Tenant, resource: Resource): Promise<AuthCodeResponse> {
const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://microsoft.azurecore`));
const { nonce, codeVerifier, codeChallenge } = this.createCryptoValuesAdal();
const port = (callbackUri.authority.match(/:([0-9]*)$/) || [])[1] || (callbackUri.scheme === 'https' ? 443 : 80);
const state = `${port},${encodeURIComponent(nonce)},${encodeURIComponent(callbackUri.query)}`;
@@ -94,8 +165,8 @@ export class AzureAuthCodeGrant extends AzureAuth {
client_id: this.clientId,
redirect_uri: this.redirectUri,
state,
prompt: 'select_account',
code_challenge_method: 'S256',
prompt: Constants.SELECT_ACCOUNT,
code_challenge_method: Constants.S256_CODE_CHALLENGE_METHOD,
code_challenge: codeChallenge,
resource: resource.id
};
@@ -141,7 +212,7 @@ export class AzureAuthCodeGrant extends AzureAuth {
}, {});
}
private async loginDesktop(tenant: Tenant, resource: Resource, authCompletePromise: Promise<void>): Promise<AuthCodeResponse> {
private async loginDesktopMsal(tenant: Tenant, resource: Resource, authCompletePromise: Promise<void>): Promise<AuthorizationCodeRequest> {
const server = new SimpleWebServer();
let serverPort: string;
@@ -151,7 +222,56 @@ export class AzureAuthCodeGrant extends AzureAuth {
const msg = localize('azure.serverCouldNotStart', 'Server could not start. This could be a permissions error or an incompatibility on your system. You can try enabling device code authentication from settings.');
throw new AzureAuthError(msg, 'Server could not start', ex);
}
const { nonce, codeVerifier, codeChallenge } = this.createCryptoValues();
await this.createCryptoValuesMsal();
const state = `${serverPort},${this.pkceCodes.nonce}`;
try {
let authUrlRequest: AuthorizationUrlRequest;
authUrlRequest = {
scopes: this.scopes,
redirectUri: `${this.redirectUri}:${serverPort}/redirect`,
codeChallenge: this.pkceCodes.codeChallenge,
codeChallengeMethod: this.pkceCodes.challengeMethod,
prompt: Constants.SELECT_ACCOUNT,
authority: `${this.loginEndpointUrl}${tenant.id}`,
state: state
};
let authCodeRequest: AuthorizationCodeRequest;
authCodeRequest = {
scopes: this.scopes,
redirectUri: `${this.redirectUri}:${serverPort}/redirect`,
codeVerifier: this.pkceCodes.codeVerifier,
authority: `${this.loginEndpointUrl}${tenant.id}`,
code: ''
};
let authCodeUrl = await this.clientApplication.getAuthCodeUrl(authUrlRequest);
await vscode.env.openExternal(vscode.Uri.parse(`http://localhost:${serverPort}/signin?nonce=${encodeURIComponent(this.pkceCodes.nonce)}`));
const authCode = await this.addServerListeners(server, this.pkceCodes.nonce, authCodeUrl, authCompletePromise);
authCodeRequest.code = authCode;
return authCodeRequest;
}
catch (e) {
Logger.error('MSAL: Error requesting auth code', e);
throw new AzureAuthError('error', 'Error requesting auth code', e);
}
}
private async loginDesktopAdal(tenant: Tenant, resource: Resource, authCompletePromise: Promise<void>): Promise<AuthCodeResponse> {
const server = new SimpleWebServer();
let serverPort: string;
try {
serverPort = await server.startup();
} catch (ex) {
const msg = localize('azure.serverCouldNotStart', 'Server could not start. This could be a permissions error or an incompatibility on your system. You can try enabling device code authentication from settings.');
throw new AzureAuthError(msg, 'Server could not start', ex);
}
const { nonce, codeVerifier, codeChallenge } = this.createCryptoValuesAdal();
const state = `${serverPort},${encodeURIComponent(nonce)}`;
const loginQuery = {
response_type: 'code',
@@ -159,8 +279,8 @@ export class AzureAuthCodeGrant extends AzureAuth {
client_id: this.clientId,
redirect_uri: `${this.redirectUri}:${serverPort}/redirect`,
state,
prompt: 'select_account',
code_challenge_method: 'S256',
prompt: Constants.SELECT_ACCOUNT,
code_challenge_method: Constants.S256_CODE_CHALLENGE_METHOD,
code_challenge: codeChallenge,
resource: resource.endpoint
};
@@ -272,13 +392,21 @@ export class AzureAuthCodeGrant extends AzureAuth {
}
private createCryptoValues(): CryptoValues {
private createCryptoValuesAdal(): CryptoValues {
const nonce = crypto.randomBytes(16).toString('base64');
const codeVerifier = this.toBase64UrlEncoding(crypto.randomBytes(32).toString('base64'));
const codeChallenge = this.toBase64UrlEncoding(crypto.createHash('sha256').update(codeVerifier).digest('base64'));
const challengeMethod = '';
return {
nonce, codeVerifier, codeChallenge
nonce, challengeMethod, codeVerifier, codeChallenge
};
}
private async createCryptoValuesMsal(): Promise<void> {
this.pkceCodes.nonce = this.cryptoProvider.createNewGuid();
const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes();
this.pkceCodes.codeVerifier = verifier;
this.pkceCodes.codeChallenge = challenge;
}
}

View File

@@ -13,7 +13,6 @@ import {
DeviceCodeCheckPostData,
} from './azureAuth';
import {
AzureAccountProviderMetadata,
AzureAuthType,
@@ -21,8 +20,10 @@ import {
Resource
} from 'azurecore';
import { Deferred } from '../interfaces';
import { SimpleTokenCache } from '../simpleTokenCache';
import { AuthenticationResult, DeviceCodeRequest, PublicClientApplication } from '@azure/msal-node';
import { SimpleTokenCache } from '../utils/simpleTokenCache';
import { Logger } from '../../utils/Logger';
const localize = nls.loadMessageBundle();
interface DeviceCodeLogin { // https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code
@@ -50,12 +51,34 @@ export class AzureDeviceCode extends AzureAuth {
tokenCache: SimpleTokenCache,
context: vscode.ExtensionContext,
uriEventEmitter: vscode.EventEmitter<vscode.Uri>,
clientApplication: PublicClientApplication,
authLibrary: string
) {
super(metadata, tokenCache, context, uriEventEmitter, AzureAuthType.DeviceCode, AzureDeviceCode.USER_FRIENDLY_NAME);
super(metadata, tokenCache, context, clientApplication, uriEventEmitter, AzureAuthType.DeviceCode, AzureDeviceCode.USER_FRIENDLY_NAME, authLibrary);
this.pageTitle = localize('addAccount', "Add {0} account", this.metadata.displayName);
}
protected async login(tenant: Tenant, resource: Resource): Promise<{ response: OAuthTokenResponse, authComplete: Deferred<void, Error> }> {
protected async loginMsal(tenant: Tenant, resource: Resource): Promise<{ response: AuthenticationResult | null, authComplete: Deferred<void, Error> }> {
let authCompleteDeferred: Deferred<void, Error>;
let authCompletePromise = new Promise<void>((resolve, reject) => authCompleteDeferred = { resolve, reject });
const deviceCodeRequest: DeviceCodeRequest = {
scopes: this.scopes,
authority: `${this.loginEndpointUrl}${tenant.id}`,
deviceCodeCallback: async (response) => {
await azdata.accounts.beginAutoOAuthDeviceCode(this.metadata.id, this.pageTitle, response.message, response.userCode, response.verificationUri);
}
};
const authResult = await this.clientApplication.acquireTokenByDeviceCode(deviceCodeRequest);
this.closeOnceComplete(authCompletePromise).catch(Logger.error);
return {
response: authResult,
authComplete: authCompleteDeferred!
};
}
protected async loginAdal(tenant: Tenant, resource: Resource): Promise<{ response: OAuthTokenResponse, authComplete: Deferred<void, Error> }> {
let authCompleteDeferred: Deferred<void, Error>;
let authCompletePromise = new Promise<void>((resolve, reject) => authCompleteDeferred = { resolve, reject });
@@ -79,7 +102,7 @@ export class AzureDeviceCode extends AzureAuth {
const currentTime = new Date().getTime() / 1000;
const expiresOn = `${currentTime + finalDeviceLogin.expires_in}`;
const result = await this.getTokenHelper(tenant, resource, accessTokenString, refreshTokenString, expiresOn);
const result = await this.getTokenHelperAdal(tenant, resource, accessTokenString, refreshTokenString, expiresOn);
this.closeOnceComplete(authCompletePromise).catch(Logger.error);
return {
@@ -93,7 +116,6 @@ export class AzureDeviceCode extends AzureAuth {
azdata.accounts.endAutoOAuthDeviceCode();
}
private setupPolling(info: DeviceCodeLogin): Promise<DeviceCodeLoginResult> {
const timeoutMessage = localize('azure.timeoutDeviceCode', 'Timed out when waiting for device code login.');
const fiveMinutes = 5 * 60 * 1000;
@@ -130,18 +152,15 @@ export class AzureDeviceCode extends AzureAuth {
};
const postResult = await this.makePostRequest(uri, postData);
const result: DeviceCodeLoginResult = postResult.data;
return result;
} catch (ex) {
console.log(ex);
console.log('Unexpected error making Azure auth request', 'azureCore.checkForResult', JSON.stringify(ex?.response?.data, undefined, 2));
Logger.error('Unexpected error making Azure auth request', 'azureCore.checkForResult', JSON.stringify(ex?.response?.data, undefined, 2));
throw new Error(msg);
}
}
public override async autoOAuthCancelled(): Promise<void> {
return azdata.accounts.endAutoOAuthDeviceCode();
}

View File

@@ -13,31 +13,37 @@ import {
AzureAccount
} from 'azurecore';
import { Deferred } from './interfaces';
import { SimpleTokenCache } from './simpleTokenCache';
import { AuthenticationResult, PublicClientApplication } from '@azure/msal-node';
import { SimpleTokenCache } from './utils/simpleTokenCache';
import { Logger } from '../utils/Logger';
import { MultiTenantTokenResponse, Token, AzureAuth } from './auths/azureAuth';
import { AzureAuthCodeGrant } from './auths/azureAuthCodeGrant';
import { AzureDeviceCode } from './auths/azureDeviceCode';
import { filterAccounts } from '../azureResource/utils';
import * as Constants from '../constants';
const localize = nls.loadMessageBundle();
export class AzureAccountProvider implements azdata.AccountProvider, vscode.Disposable {
private static readonly CONFIGURATION_SECTION = 'accounts.azure.auth';
private readonly authMappings = new Map<AzureAuthType, AzureAuth>();
private initComplete!: Deferred<void, Error>;
private initCompletePromise: Promise<void> = new Promise<void>((resolve, reject) => this.initComplete = { resolve, reject });
public clientApplication: PublicClientApplication;
constructor(
metadata: AzureAccountProviderMetadata,
tokenCache: SimpleTokenCache,
context: vscode.ExtensionContext,
clientApplication: PublicClientApplication,
uriEventHandler: vscode.EventEmitter<vscode.Uri>,
private readonly authLibrary: string,
private readonly forceDeviceCode: boolean = false
) {
this.clientApplication = clientApplication;
vscode.workspace.onDidChangeConfiguration((changeEvent) => {
const impact = changeEvent.affectsConfiguration(AzureAccountProvider.CONFIGURATION_SECTION);
if (impact === true) {
const impactProvider = changeEvent.affectsConfiguration(Constants.AccountsAzureAuthSection);
if (impactProvider === true) {
this.handleAuthMapping(metadata, tokenCache, context, uriEventHandler);
}
});
@@ -50,22 +56,27 @@ export class AzureAccountProvider implements azdata.AccountProvider, vscode.Disp
}
clearTokenCache(): Thenable<void> {
return this.getAuthMethod().deleteAllCache();
return this.authLibrary === Constants.AuthLibrary.MSAL
? this.getAuthMethod().deleteAllCacheMsal()
// fallback to ADAL as default
: this.getAuthMethod().deleteAllCacheAdal();
}
private handleAuthMapping(metadata: AzureAccountProviderMetadata, tokenCache: SimpleTokenCache, context: vscode.ExtensionContext, uriEventHandler: vscode.EventEmitter<vscode.Uri>) {
this.authMappings.forEach(m => m.dispose());
this.authMappings.clear();
const configuration = vscode.workspace.getConfiguration(AzureAccountProvider.CONFIGURATION_SECTION);
const codeGrantMethod: boolean = configuration.get<boolean>('codeGrant', false);
const deviceCodeMethod: boolean = configuration.get<boolean>('deviceCode', false);
const configuration = vscode.workspace.getConfiguration(Constants.AccountsAzureAuthSection);
const codeGrantMethod: boolean = configuration.get<boolean>(Constants.AuthType.CodeGrant, false);
const deviceCodeMethod: boolean = configuration.get<boolean>(Constants.AuthType.DeviceCode, false);
if (codeGrantMethod === true && !this.forceDeviceCode) {
this.authMappings.set(AzureAuthType.AuthCodeGrant, new AzureAuthCodeGrant(metadata, tokenCache, context, uriEventHandler));
} else if (deviceCodeMethod === true || this.forceDeviceCode) {
this.authMappings.set(AzureAuthType.DeviceCode, new AzureDeviceCode(metadata, tokenCache, context, uriEventHandler));
} else {
this.authMappings.set(AzureAuthType.AuthCodeGrant, new AzureAuthCodeGrant(metadata, tokenCache, context, uriEventHandler, this.clientApplication, this.authLibrary));
}
if (deviceCodeMethod === true || this.forceDeviceCode) {
this.authMappings.set(AzureAuthType.DeviceCode, new AzureDeviceCode(metadata, tokenCache, context, uriEventHandler, this.clientApplication, this.authLibrary));
}
if (codeGrantMethod === false && deviceCodeMethod === false && !this.forceDeviceCode) {
console.error('No authentication methods selected');
}
}
@@ -94,14 +105,26 @@ export class AzureAccountProvider implements azdata.AccountProvider, vscode.Disp
private async _initialize(storedAccounts: AzureAccount[]): Promise<AzureAccount[]> {
const accounts: AzureAccount[] = [];
console.log(`Initializing stored accounts ${JSON.stringify(accounts)}`);
for (let account of storedAccounts) {
Logger.verbose(`Initializing stored accounts ${JSON.stringify(accounts)}`);
const updatedAccounts = filterAccounts(storedAccounts, this.authLibrary);
for (let account of updatedAccounts) {
const azureAuth = this.getAuthMethod(account);
if (!azureAuth) {
account.isStale = true;
accounts.push(account);
} else {
accounts.push(await azureAuth.refreshAccess(account));
account.isStale = false;
if (this.authLibrary === Constants.AuthLibrary.MSAL) {
// Check MSAL Cache before adding account, to mark it as stale if it is not present in cache
const accountInCache = await azureAuth.getAccountFromMsalCache(account.key.accountId);
if (!accountInCache) {
account.isStale = true;
}
accounts.push(account);
} else { // fallback to ADAL as default
accounts.push(await azureAuth.refreshAccessAdal(account));
}
}
}
this.initComplete.resolve();
@@ -120,10 +143,56 @@ export class AzureAccountProvider implements azdata.AccountProvider, vscode.Disp
private async _getAccountSecurityToken(account: AzureAccount, tenantId: string, resource: azdata.AzureResource): Promise<Token | undefined> {
await this.initCompletePromise;
const azureAuth = this.getAuthMethod(account);
Logger.pii(`Getting account security token for ${JSON.stringify(account.key)} (tenant ${tenantId}). Auth Method = ${azureAuth.userFriendlyName}`, [], []);
return azureAuth?.getAccountSecurityToken(account, tenantId, resource);
if (azureAuth) {
Logger.piiSanitized(`Getting account security token for ${JSON.stringify(account.key)} (tenant ${tenantId}). Auth Method = ${azureAuth.userFriendlyName}`, [], []);
if (this.authLibrary === Constants.AuthLibrary.MSAL) {
tenantId = tenantId || account.properties.owningTenant.id;
let authResult = await azureAuth.getTokenMsal(account.key.accountId, resource, tenantId);
if (this.isAuthenticationResult(authResult) && authResult.account && authResult.account.idTokenClaims) {
const token: Token = {
key: authResult.account.homeAccountId,
token: authResult.accessToken,
tokenType: authResult.tokenType,
expiresOn: authResult.account.idTokenClaims.exp
};
return token;
} else {
Logger.error(`MSAL: getToken call failed`);
// Throw error with MSAL-specific code/message, else throw generic error message
if (this.isProviderError(authResult)) {
throw new Error(localize('msalTokenError', `{0} occurred when acquiring token. \n{1}`, authResult.errorCode, authResult.errorMessage));
} else {
throw new Error(localize('genericTokenError', 'Failed to get token'));
}
}
} else { // fallback to ADAL as default
return azureAuth.getAccountSecurityTokenAdal(account, tenantId, resource);
}
} else {
account.isStale = true;
Logger.error(`_getAccountSecurityToken: Authentication method not found for account ${account.displayInfo.displayName}`);
throw Error('Failed to get authentication method, please remove and re-add the account');
}
}
private isAuthenticationResult(result: AuthenticationResult | azdata.ProviderError | null): result is AuthenticationResult {
if (result) {
return typeof (<AuthenticationResult>result).accessToken === 'string';
} else {
return false;
}
}
private isProviderError(result: AuthenticationResult | azdata.ProviderError | null): result is azdata.ProviderError {
if (result) {
return typeof (<azdata.ProviderError>result).errorMessage === 'string';
} else {
return false;
}
}
private async _getSecurityToken(account: AzureAccount, resource: azdata.AzureResource): Promise<MultiTenantTokenResponse | undefined> {
void vscode.window.showInformationMessage(localize('azure.deprecatedGetSecurityToken', "A call was made to azdata.accounts.getSecurityToken, this method is deprecated and will be removed in future releases. Please use getAccountSecurityToken instead."));
const azureAccount = account as AzureAccount;
@@ -176,7 +245,6 @@ export class AzureAccountProvider implements azdata.AccountProvider, vscode.Disp
return pick.azureAuth.startLogin();
}
refresh(account: AzureAccount): Thenable<AzureAccount | azdata.PromptFailedResult> {
return this._refresh(account);
}

View File

@@ -3,16 +3,23 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as azdata from 'azdata';
import * as events from 'events';
import * as nls from 'vscode-nls';
import * as vscode from 'vscode';
import { SimpleTokenCache } from './simpleTokenCache';
import { promises as fsPromises } from 'fs';
import { SimpleTokenCache } from './utils/simpleTokenCache';
import providerSettings from './providerSettings';
import { AzureAccountProvider as AzureAccountProvider } from './azureAccountProvider';
import { AzureAccountProviderMetadata } from 'azurecore';
import { ProviderSettings } from './interfaces';
import { MsalCachePluginProvider } from './utils/msalCachePlugin';
import * as loc from '../localizedConstants';
import { Configuration, PublicClientApplication } from '@azure/msal-node';
import * as Constants from '../constants';
import { Logger } from '../utils/Logger';
import { ILoggerCallback, LogLevel as MsalLogLevel } from "@azure/msal-common";
let localize = nls.loadMessageBundle();
@@ -23,22 +30,21 @@ class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.
}
export class AzureAccountProviderService implements vscode.Disposable {
// CONSTANTS ///////////////////////////////////////////////////////////////
private static CommandClearTokenCache = 'accounts.clearTokenCache';
private static ConfigurationSection = 'accounts.azure.cloud';
private static CredentialNamespace = 'azureAccountProviderCredentials';
// MEMBER VARIABLES ////////////////////////////////////////////////////////
private _disposables: vscode.Disposable[] = [];
private _accountDisposals: { [accountProviderId: string]: vscode.Disposable } = {};
private _accountProviders: { [accountProviderId: string]: azdata.AccountProvider } = {};
private _credentialProvider: azdata.CredentialProvider | undefined = undefined;
private _cachePluginProvider: MsalCachePluginProvider | undefined = undefined;
private _configChangePromiseChain: Thenable<void> = Promise.resolve();
private _currentConfig: vscode.WorkspaceConfiguration | undefined = undefined;
private _event: events.EventEmitter = new events.EventEmitter();
private readonly _uriEventHandler: UriEventHandler = new UriEventHandler();
public clientApplication!: PublicClientApplication;
constructor(private _context: vscode.ExtensionContext, private _userStoragePath: string) {
constructor(private _context: vscode.ExtensionContext,
private _userStoragePath: string,
private _authLibrary: string) {
this._disposables.push(vscode.window.registerUriHandler(this._uriEventHandler));
}
@@ -47,17 +53,16 @@ export class AzureAccountProviderService implements vscode.Disposable {
let self = this;
// Register commands
this._context.subscriptions.push(vscode.commands.registerCommand(
AzureAccountProviderService.CommandClearTokenCache,
() => { self._event.emit(AzureAccountProviderService.CommandClearTokenCache); }
this._context.subscriptions.push(vscode.commands.registerCommand(Constants.AccountsClearTokenCacheCommand,
() => { self._event.emit(Constants.AccountsClearTokenCacheCommand); }
));
this._event.on(AzureAccountProviderService.CommandClearTokenCache, () => { void self.onClearTokenCache(); });
this._event.on(Constants.AccountsClearTokenCacheCommand, () => { void self.onClearTokenCache(); });
// 1) Get a credential provider
// 2a) Store the credential provider for use later
// 2b) Register the configuration change handler
// 2c) Perform an initial config change handling
return azdata.credentials.getProvider(AzureAccountProviderService.CredentialNamespace)
return azdata.credentials.getProvider(Constants.AzureAccountProviderCredentials)
.then(credProvider => {
this._credentialProvider = credProvider;
@@ -103,7 +108,7 @@ export class AzureAccountProviderService implements vscode.Disposable {
// Add a new change processing onto the existing promise change
await this._configChangePromiseChain;
// Grab the stored config and the latest config
let newConfig = vscode.workspace.getConfiguration(AzureAccountProviderService.ConfigurationSection);
let newConfig = vscode.workspace.getConfiguration(Constants.AccountsAzureCloudSection);
let oldConfig = this._currentConfig;
this._currentConfig = newConfig;
@@ -138,22 +143,84 @@ export class AzureAccountProviderService implements vscode.Disposable {
}
private async registerAccountProvider(provider: ProviderSettings): Promise<void> {
const isSaw: boolean = vscode.env.appName.toLowerCase().indexOf(Constants.Saw) > 0;
const noSystemKeychain = vscode.workspace.getConfiguration(Constants.AzureSection).get<boolean>(Constants.NoSystemKeyChainSection);
const tokenCacheKey = `azureTokenCache-${provider.metadata.id}`;
const tokenCacheKeyMsal = Constants.MSALCacheName;
await this.clearOldCacheIfExists();
try {
const noSystemKeychain = vscode.workspace.getConfiguration('azure').get<boolean>('noSystemKeychain');
let tokenCacheKey = `azureTokenCache-${provider.metadata.id}`;
if (!this._credentialProvider) {
throw new Error('Credential provider not registered');
}
// ADAL Token Cache
let simpleTokenCache = new SimpleTokenCache(tokenCacheKey, this._userStoragePath, noSystemKeychain, this._credentialProvider);
await simpleTokenCache.init();
const isSaw: boolean = vscode.env.appName.toLowerCase().indexOf('saw') > 0;
let accountProvider = new AzureAccountProvider(provider.metadata as AzureAccountProviderMetadata, simpleTokenCache, this._context, this._uriEventHandler, isSaw);
// MSAL Cache Plugin
this._cachePluginProvider = new MsalCachePluginProvider(tokenCacheKeyMsal, this._userStoragePath, this._credentialProvider);
const msalConfiguration: Configuration = {
auth: {
clientId: provider.metadata.settings.clientId,
authority: 'https://login.windows.net/common'
},
system: {
loggerOptions: {
loggerCallback: this.getLoggerCallback(),
logLevel: MsalLogLevel.Trace,
piiLoggingEnabled: true,
},
},
cache: {
cachePlugin: this._cachePluginProvider?.getCachePlugin()
}
}
this.clientApplication = new PublicClientApplication(msalConfiguration);
let accountProvider = new AzureAccountProvider(provider.metadata as AzureAccountProviderMetadata,
simpleTokenCache, this._context, this.clientApplication, this._uriEventHandler, this._authLibrary, isSaw);
this._accountProviders[provider.metadata.id] = accountProvider;
this._accountDisposals[provider.metadata.id] = azdata.accounts.registerAccountProvider(provider.metadata, accountProvider);
} catch (e) {
console.error(`Failed to register account provider: ${e}`);
console.error(`Failed to register account provider, isSaw: ${isSaw}: ${e}`);
}
}
/**
* Clears old cache file that is no longer needed on system.
*/
private async clearOldCacheIfExists(): Promise<void> {
let filePath = path.join(this._userStoragePath, Constants.oldMsalCacheFileName);
try {
await fsPromises.access(filePath);
await fsPromises.unlink('file:' + filePath);
Logger.verbose(`Old cache file removed successfully.`);
} catch (e) {
if (e.code !== 'ENOENT') {
Logger.verbose(`Error occurred while removing old cache file: ${e}`);
} // else file doesn't exist.
}
}
private getLoggerCallback(): ILoggerCallback {
return (level: number, message: string, containsPii: boolean) => {
if (!containsPii) {
switch (level) {
case MsalLogLevel.Error:
Logger.error(message);
break;
case MsalLogLevel.Info:
Logger.info(message);
break;
case MsalLogLevel.Verbose:
default:
Logger.verbose(message);
break;
}
} else {
Logger.pii(message);
}
}
}

View File

@@ -39,7 +39,7 @@ const publicAzureSettings: ProviderSettings = {
},
graphResource: {
id: SettingIds.graph,
endpoint: 'https://graph.windows.net',
endpoint: 'https://graph.windows.net/',
azureResourceId: AzureResource.Graph
},
msGraphResource: {
@@ -49,7 +49,7 @@ const publicAzureSettings: ProviderSettings = {
},
armResource: {
id: SettingIds.arm,
endpoint: 'https://management.azure.com',
endpoint: 'https://management.azure.com/',
azureResourceId: AzureResource.ResourceManagement
},
sqlResource: {
@@ -59,38 +59,38 @@ const publicAzureSettings: ProviderSettings = {
},
ossRdbmsResource: {
id: SettingIds.ossrdbms,
endpoint: 'https://ossrdbms-aad.database.windows.net',
endpoint: 'https://ossrdbms-aad.database.windows.net/',
azureResourceId: AzureResource.OssRdbms
},
azureKeyVaultResource: {
id: SettingIds.vault,
endpoint: 'https://vault.azure.net',
endpoint: 'https://vault.azure.net/',
azureResourceId: AzureResource.AzureKeyVault
},
azureDevOpsResource: {
id: SettingIds.ado,
endpoint: '499b84ac-1321-427f-aa17-267ca6975798',
endpoint: '499b84ac-1321-427f-aa17-267ca6975798/',
azureResourceId: AzureResource.AzureDevOps,
},
azureLogAnalyticsResource: {
id: SettingIds.ala,
endpoint: 'https://api.loganalytics.io',
endpoint: 'https://api.loganalytics.io/',
azureResourceId: AzureResource.AzureLogAnalytics,
},
azureStorageResource: {
id: SettingIds.storage,
endpoint: '',
endpointSuffix: '.core.windows.net',
endpointSuffix: '.core.windows.net/',
azureResourceId: AzureResource.AzureStorage
},
azureKustoResource: {
id: SettingIds.kusto,
endpoint: 'https://kusto.kusto.windows.net',
endpoint: 'https://kusto.kusto.windows.net/',
azureResourceId: AzureResource.AzureKusto,
},
powerBiResource: {
id: SettingIds.powerbi,
endpoint: 'https://analysis.windows.net/powerbi/api',
endpoint: 'https://analysis.windows.net/powerbi/api/',
azureResourceId: AzureResource.PowerBi
},
redirectUri: 'http://localhost',
@@ -119,12 +119,12 @@ const usGovAzureSettings: ProviderSettings = {
},
graphResource: {
id: SettingIds.graph,
endpoint: 'https://graph.windows.net',
endpoint: 'https://graph.windows.net/',
azureResourceId: AzureResource.Graph
},
armResource: {
id: SettingIds.arm,
endpoint: 'https://management.usgovcloudapi.net',
endpoint: 'https://management.usgovcloudapi.net/',
azureResourceId: AzureResource.ResourceManagement
},
sqlResource: {
@@ -134,28 +134,28 @@ const usGovAzureSettings: ProviderSettings = {
},
ossRdbmsResource: {
id: SettingIds.ossrdbms,
endpoint: 'https://ossrdbms-aad.database.usgovcloudapi.net',
endpoint: 'https://ossrdbms-aad.database.usgovcloudapi.net/',
azureResourceId: AzureResource.OssRdbms
},
azureKeyVaultResource: {
id: SettingIds.vault,
endpoint: 'https://vault.usgovcloudapi.net',
endpoint: 'https://vault.usgovcloudapi.net/',
azureResourceId: AzureResource.AzureKeyVault
},
azureLogAnalyticsResource: {
id: SettingIds.ala,
endpoint: 'https://api.loganalytics.us',
endpoint: 'https://api.loganalytics.us/',
azureResourceId: AzureResource.AzureLogAnalytics,
},
azureStorageResource: {
id: SettingIds.storage,
endpoint: '',
endpointSuffix: '.core.usgovcloudapi.net',
endpointSuffix: '.core.usgovcloudapi.net/',
azureResourceId: AzureResource.AzureStorage
},
powerBiResource: {
id: SettingIds.powerbi,
endpoint: 'https://analysis.windows.net/powerbi/api',
endpoint: 'https://analysis.windows.net/powerbi/api/',
azureResourceId: AzureResource.PowerBi
},
redirectUri: 'http://localhost',
@@ -168,115 +168,6 @@ const usGovAzureSettings: ProviderSettings = {
}
};
const usNatAzureSettings: ProviderSettings = {
configKey: 'enableUsNatCloud',
metadata: {
displayName: localize('usNatCloudDisplayName', "Azure (US National)"),
id: 'azure_usNatCloud',
settings: {
host: 'https://login.microsoftonline.eaglex.ic.gov/',
clientId: 'a69788c6-1d43-44ed-9ca3-b83e194da255',
microsoftResource: {
id: SettingIds.marm,
endpoint: 'https://management.azure.eaglex.ic.gov/',
azureResourceId: AzureResource.MicrosoftResourceManagement
},
graphResource: {
id: SettingIds.graph,
endpoint: 'https://graph.eaglex.ic.gov',
azureResourceId: AzureResource.Graph
},
armResource: {
id: SettingIds.arm,
endpoint: 'https://management.core.eaglex.ic.gov/',
azureResourceId: AzureResource.ResourceManagement
},
sqlResource: {
id: SettingIds.sql,
endpoint: 'https://database.cloudapi.eaglex.ic.gov/',
azureResourceId: AzureResource.Sql
},
ossRdbmsResource: {
id: SettingIds.ossrdbms,
endpoint: 'https://ossrdbms-aad.database.cloudapi.eaglex.ic.gov',
azureResourceId: AzureResource.OssRdbms
},
azureKeyVaultResource: {
id: SettingIds.vault,
endpoint: 'https://vault.cloudapi.eaglex.ic.gov',
azureResourceId: AzureResource.AzureKeyVault
},
azureLogAnalyticsResource: {
id: SettingIds.ala,
endpoint: 'https://api.loganalytics.azure.eaglex.ic.gov',
azureResourceId: AzureResource.AzureLogAnalytics,
},
azureStorageResource: {
id: SettingIds.storage,
endpoint: '',
endpointSuffix: '.core.eaglex.ic.gov',
azureResourceId: AzureResource.AzureStorage
},
redirectUri: 'http://localhost',
scopes: [
'openid', 'email', 'profile', 'offline_access',
'https://management.core.eaglex.ic.gov/user_impersonation'
],
portalEndpoint: 'https://portal.azure.eaglex.ic.gov/'
}
}
};
const germanyAzureSettings: ProviderSettings = {
configKey: 'enableGermanyCloud',
metadata: {
displayName: localize('germanyCloud', "Azure (Germany)"),
id: 'azure_germanyCloud',
settings: {
host: 'https://login.microsoftazure.de/',
clientId: 'a69788c6-1d43-44ed-9ca3-b83e194da255',
graphResource: {
id: SettingIds.graph,
endpoint: 'https://graph.cloudapi.de',
azureResourceId: AzureResource.Graph
},
msGraphResource: {
id: SettingIds.msgraph,
endpoint: 'https://graph.microsoft.de',
azureResourceId: AzureResource.MsGraph
},
armResource: {
id: SettingIds.arm,
endpoint: 'https://management.microsoftazure.de',
azureResourceId: AzureResource.ResourceManagement
},
azureKeyVaultResource: {
id: SettingIds.vault,
endpoint: 'https://vault.microsoftazure.de',
azureResourceId: AzureResource.AzureKeyVault
},
azureStorageResource: {
id: SettingIds.storage,
endpoint: '',
endpointSuffix: '.core.cloudapi.de',
azureResourceId: AzureResource.AzureStorage
},
powerBiResource: {
id: SettingIds.powerbi,
endpoint: 'https://analysis.windows.net/powerbi/api',
azureResourceId: AzureResource.PowerBi
},
redirectUri: 'http://localhost',
scopes: [
'openid', 'email', 'profile', 'offline_access',
'https://management.microsoftazure.de/user_impersonation'
],
portalEndpoint: 'https://portal.microsoftazure.de/'
}
}
};
const chinaAzureSettings: ProviderSettings = {
configKey: 'enableChinaCloud',
metadata: {
@@ -340,5 +231,5 @@ const chinaAzureSettings: ProviderSettings = {
}
}
};
const allSettings = [publicAzureSettings, usGovAzureSettings, usNatAzureSettings, germanyAzureSettings, chinaAzureSettings];
const allSettings = [publicAzureSettings, usGovAzureSettings, chinaAzureSettings];
export default allSettings;

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { promises as fs, constants as fsConstants } from 'fs';
import { Logger } from '../../utils/Logger';
export type ReadWriteHook = (contents: string) => Promise<string>;
const noOpHook: ReadWriteHook = async (contents): Promise<string> => {
@@ -88,7 +89,6 @@ export class FileDatabase {
this.isDirty = true;
}
public async initialize(): Promise<void> {
this.isInitialized = true;
this.saveInterval = setInterval(() => this.save(), 20 * 1000);
@@ -98,7 +98,7 @@ export class FileDatabase {
fileContents = await fs.readFile(this.dbPath, { encoding: 'utf8' });
fileContents = await this.readHook(fileContents);
} catch (ex) {
console.log(`file db does not exist ${ex}`);
Logger.error(`Error occurred when initializing File Database from file system cache, ADAL cache will be reset: ${ex}`);
await this.createFile();
this.db = {};
this.isDirty = true;
@@ -108,7 +108,7 @@ export class FileDatabase {
try {
this.db = JSON.parse(fileContents);
} catch (ex) {
console.log(`DB was corrupted, resetting it ${ex}`);
Logger.error(`Error occurred when reading file database contents as JSON, ADAL cache will be reset: ${ex}`);
await this.createFile();
this.db = {};
}
@@ -140,7 +140,7 @@ export class FileDatabase {
this.isDirty = false;
} catch (ex) {
console.log(`File saving is erroring! ${ex}`);
Logger.error(`Error occurred while saving cache contents to file storage, this may cause issues with ADAL cache persistence: ${ex}`);
} finally {
this.isSaving = false;
}

View File

@@ -0,0 +1,121 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as os from 'os';
import * as crypto from 'crypto';
import * as vscode from 'vscode';
import { AuthLibrary } from '../../constants';
import * as LocalizedConstants from '../../localizedConstants';
import { Logger } from '../../utils/Logger';
export class FileEncryptionHelper {
constructor(
private readonly _authLibrary: AuthLibrary,
private readonly _credentialService: azdata.CredentialProvider,
protected readonly _fileName: string
) {
this._algorithm = this._authLibrary === AuthLibrary.MSAL ? 'aes-256-cbc' : 'aes-256-gcm';
this._bufferEncoding = this._authLibrary === AuthLibrary.MSAL ? 'utf16le' : 'hex';
this._binaryEncoding = this._authLibrary === AuthLibrary.MSAL ? 'base64' : 'hex';
}
private _algorithm: string;
private _bufferEncoding: BufferEncoding;
private _binaryEncoding: crypto.HexBase64BinaryEncoding;
private _ivBuffer: Buffer | undefined;
private _keyBuffer: Buffer | undefined;
public async init(): Promise<void> {
const ivCredId = `${this._fileName}-iv`;
const keyCredId = `${this._fileName}-key`;
const iv = await this.readEncryptionKey(ivCredId);
const key = await this.readEncryptionKey(keyCredId);
if (!iv || !key) {
this._ivBuffer = crypto.randomBytes(16);
this._keyBuffer = crypto.randomBytes(32);
if (!await this.saveEncryptionKey(ivCredId, this._ivBuffer.toString(this._bufferEncoding))
|| !await this.saveEncryptionKey(keyCredId, this._keyBuffer.toString(this._bufferEncoding))) {
Logger.error(`Encryption keys could not be saved in credential store, this will cause access token persistence issues.`);
await this.showCredSaveErrorOnWindows();
}
} else {
this._ivBuffer = Buffer.from(iv, this._bufferEncoding);
this._keyBuffer = Buffer.from(key, this._bufferEncoding);
}
}
fileSaver = async (content: string): Promise<string> => {
if (!this._keyBuffer || !this._ivBuffer) {
await this.init();
}
const cipherIv = crypto.createCipheriv(this._algorithm, this._keyBuffer!, this._ivBuffer!);
let cipherText = `${cipherIv.update(content, 'utf8', this._binaryEncoding)}${cipherIv.final(this._binaryEncoding)}`;
if (this._authLibrary === AuthLibrary.ADAL) {
cipherText += `%${(cipherIv as crypto.CipherGCM).getAuthTag().toString(this._binaryEncoding)}`;
}
return cipherText;
}
fileOpener = async (content: string): Promise<string> => {
if (!this._keyBuffer || !this._ivBuffer) {
await this.init();
}
let plaintext = content;
const decipherIv = crypto.createDecipheriv(this._algorithm, this._keyBuffer!, this._ivBuffer!);
if (this._authLibrary === AuthLibrary.ADAL) {
const split = content.split('%');
if (split.length !== 2) {
throw new Error('File didn\'t contain the auth tag.');
}
(decipherIv as crypto.DecipherGCM).setAuthTag(Buffer.from(split[1], this._binaryEncoding));
plaintext = split[0];
}
return `${decipherIv.update(plaintext, this._binaryEncoding, 'utf8')}${decipherIv.final('utf8')}`;
}
protected async readEncryptionKey(credentialId: string): Promise<string | undefined> {
return (await this._credentialService.readCredential(credentialId))?.password;
}
protected async saveEncryptionKey(credentialId: string, password: string): Promise<boolean> {
let status: boolean = false;
try {
await this._credentialService.saveCredential(credentialId, password)
.then((result) => {
status = result;
if (result) {
Logger.info(`FileEncryptionHelper: Successfully saved encryption key ${credentialId} for ${this._authLibrary} persistent cache encryption in system credential store.`);
}
}, (e => {
throw Error(`FileEncryptionHelper: Could not save encryption key: ${credentialId}: ${e}`);
}));
} catch (ex) {
if (os.platform() === 'win32') {
Logger.error(`FileEncryptionHelper: Please try cleaning saved credentials from Windows Credential Manager created by Azure Data Studio to allow creating new credentials.`);
}
Logger.error(ex);
throw ex;
}
return status;
}
protected async showCredSaveErrorOnWindows(): Promise<void> {
if (os.platform() === 'win32') {
await vscode.window.showWarningMessage(LocalizedConstants.azureCredStoreSaveFailedError,
LocalizedConstants.reloadChoice, LocalizedConstants.cancel)
.then(async (selection) => {
if (selection === LocalizedConstants.reloadChoice) {
await vscode.commands.executeCommand('workbench.action.reloadWindow');
}
}, error => {
Logger.error(error);
});
}
}
}

View File

@@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICachePlugin, TokenCacheContext } from '@azure/msal-node';
import { promises as fsPromises } from 'fs';
import * as lockFile from 'lockfile';
import * as path from 'path';
import * as azdata from 'azdata';
import { AccountsClearTokenCacheCommand, AuthLibrary } from '../../constants';
import { Logger } from '../../utils/Logger';
import { FileEncryptionHelper } from './fileEncryptionHelper';
export class MsalCachePluginProvider {
constructor(
private readonly _serviceName: string,
private readonly _msalFilePath: string,
private readonly _credentialService: azdata.CredentialProvider
) {
this._msalFilePath = path.join(this._msalFilePath, this._serviceName);
this._fileEncryptionHelper = new FileEncryptionHelper(AuthLibrary.MSAL, this._credentialService, this._serviceName);
}
private _lockTaken: boolean = false;
private _fileEncryptionHelper: FileEncryptionHelper;
private getLockfilePath(): string {
return this._msalFilePath + '.lockfile';
}
public getCachePlugin(): ICachePlugin {
const lockFilePath = this.getLockfilePath();
const beforeCacheAccess = async (cacheContext: TokenCacheContext): Promise<void> => {
await this.waitAndLock(lockFilePath);
try {
const cache = await fsPromises.readFile(this._msalFilePath, { encoding: 'utf8' });
const decryptedData = await this._fileEncryptionHelper.fileOpener(cache!);
try {
cacheContext.tokenCache.deserialize(decryptedData);
} catch (e) {
// Handle deserialization error in cache file in case file gets corrupted.
// Clearing cache here will ensure account is marked stale so re-authentication can be triggered.
Logger.verbose(`MsalCachePlugin: Error occurred when trying to read cache file, file contents will be cleared: ${e.message}`);
await fsPromises.writeFile(this._msalFilePath, '', { encoding: 'utf8' });
}
Logger.verbose(`MsalCachePlugin: Token read from cache successfully.`);
} catch (e) {
if (e.code === 'ENOENT') {
// File doesn't exist, log and continue
Logger.verbose(`MsalCachePlugin: Cache file not found on disk: ${e.code}`);
}
else {
Logger.error(`MsalCachePlugin: Failed to read from cache file: ${e}`);
Logger.verbose(`MsalCachePlugin: Error occurred when trying to read cache file, file contents will be cleared: ${e.message}`);
await fsPromises.writeFile(this._msalFilePath, '', { encoding: 'utf8' });
}
} finally {
lockFile.unlockSync(lockFilePath);
this._lockTaken = false;
}
}
const afterCacheAccess = async (cacheContext: TokenCacheContext): Promise<void> => {
if (cacheContext.cacheHasChanged) {
await this.waitAndLock(lockFilePath);
try {
const data = cacheContext.tokenCache.serialize();
const encryptedData = await this._fileEncryptionHelper.fileSaver(data!);
await fsPromises.writeFile(this._msalFilePath, encryptedData, { encoding: 'utf8' });
Logger.verbose(`MsalCachePlugin: Token written to cache successfully.`);
} catch (e) {
Logger.error(`MsalCachePlugin: Failed to write to cache file. ${e}`);
throw e;
} finally {
lockFile.unlockSync(lockFilePath);
this._lockTaken = false;
}
}
};
// This is an implementation of ICachePlugin that uses the beforeCacheAccess and afterCacheAccess callbacks to read and write to a file
// Ref https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-node-migration#enable-token-caching
// In future we should use msal-node-extensions to provide a secure storage of tokens, instead of implementing our own
// However - as of now this library does not come with pre-compiled native libraries that causes runtime issues
// Ref https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/3332
return {
beforeCacheAccess,
afterCacheAccess,
};
}
private async waitAndLock(lockFilePath: string): Promise<void> {
// Make 500 retry attempts with 100ms wait time between each attempt to allow enough time for the lock to be released.
const retries = 500;
const retryWait = 100;
// We cannot rely on lockfile.lockSync() to clear stale lockfile,
// so we check if the lockfile exists and if it does, calling unlockSync() will clear it.
if (lockFile.checkSync(lockFilePath) && !this._lockTaken) {
lockFile.unlockSync(lockFilePath);
Logger.verbose(`MsalCachePlugin: Stale lockfile found and has been removed.`);
}
let retryAttempt = 0;
while (retryAttempt <= retries) {
try {
// Use lockfile.lockSync() to ensure only one process is accessing the cache at a time.
// lockfile.lock() does not wait for async callback promise to resolve.
lockFile.lockSync(lockFilePath);
this._lockTaken = true;
break;
} catch (e) {
if (retryAttempt === retries) {
Logger.error(`MsalCachePlugin: Failed to acquire lock on cache file after ${retries} attempts.`);
throw new Error(`Failed to acquire lock on cache file after ${retries} attempts. Please attempt command: '${AccountsClearTokenCacheCommand}' to clear access token cache.`);
}
retryAttempt++;
Logger.verbose(`MsalCachePlugin: Failed to acquire lock on cache file. Retrying in ${retryWait} ms.`);
await new Promise(resolve => setTimeout(resolve, retryWait));
}
}
}
}

View File

@@ -4,9 +4,10 @@
*--------------------------------------------------------------------------------------------*/
import * as keytarType from 'keytar';
import { join, parse } from 'path';
import { FileDatabase } from './utils/fileDatabase';
import { FileDatabase } from './fileDatabase';
import * as azdata from 'azdata';
import * as crypto from 'crypto';
import { FileEncryptionHelper } from './fileEncryptionHelper';
import { AuthLibrary } from '../../constants';
function getSystemKeytar(): Keytar | undefined {
try {
@@ -25,42 +26,8 @@ const separator = '§';
async function getFileKeytar(filePath: string, credentialService: azdata.CredentialProvider): Promise<Keytar | undefined> {
const fileName = parse(filePath).base;
const iv = await credentialService.readCredential(`${fileName}-iv`);
const key = await credentialService.readCredential(`${fileName}-key`);
let ivBuffer: Buffer;
let keyBuffer: Buffer;
if (!iv?.password || !key?.password) {
ivBuffer = crypto.randomBytes(16);
keyBuffer = crypto.randomBytes(32);
try {
await credentialService.saveCredential(`${fileName}-iv`, ivBuffer.toString('hex'));
await credentialService.saveCredential(`${fileName}-key`, keyBuffer.toString('hex'));
} catch (ex) {
console.log(ex);
}
} else {
ivBuffer = Buffer.from(iv.password, 'hex');
keyBuffer = Buffer.from(key.password, 'hex');
}
const fileSaver = async (content: string): Promise<string> => {
const cipherIv = crypto.createCipheriv('aes-256-gcm', keyBuffer, ivBuffer);
return `${cipherIv.update(content, 'utf8', 'hex')}${cipherIv.final('hex')}%${cipherIv.getAuthTag().toString('hex')}`;
};
const fileOpener = async (content: string): Promise<string> => {
const decipherIv = crypto.createDecipheriv('aes-256-gcm', keyBuffer, ivBuffer);
const split = content.split('%');
if (split.length !== 2) {
throw new Error('File didn\'t contain the auth tag.');
}
decipherIv.setAuthTag(Buffer.from(split[1], 'hex'));
return `${decipherIv.update(split[0], 'hex', 'utf8')}${decipherIv.final('utf8')}`;
};
const db = new FileDatabase(filePath, fileOpener, fileSaver);
const fileEncryptionHelper: FileEncryptionHelper = new FileEncryptionHelper(AuthLibrary.ADAL, credentialService, fileName);
const db = new FileDatabase(filePath, fileEncryptionHelper.fileOpener, fileEncryptionHelper.fileSaver);
await db.initialize();
const fileKeytar: Keytar = {
@@ -94,6 +61,7 @@ async function getFileKeytar(filePath: string, credentialService: azdata.Credent
return fileKeytar;
}
export type Keytar = {
getPassword: typeof keytarType['getPassword'];
setPassword: typeof keytarType['setPassword'];
@@ -110,9 +78,7 @@ export class SimpleTokenCache {
private readonly userStoragePath: string,
private readonly forceFileStorage: boolean = false,
private readonly credentialService: azdata.CredentialProvider,
) {
}
) { }
async init(): Promise<void> {
this.serviceName = this.serviceName.replace(/-/g, '_');

View File

@@ -5,6 +5,7 @@
import * as http from 'http';
import * as url from 'url';
import { AddressInfo } from 'net';
import { Logger } from '../../utils/Logger';
export type WebHandler = (req: http.IncomingMessage, reqUrl: url.UrlWithParsedQuery, res: http.ServerResponse) => void;
@@ -24,7 +25,7 @@ export class SimpleWebServer {
const time = new Date().getTime();
if (time - this.lastUsed > this.autoShutoffTimer) {
console.log('Shutting off webserver...');
Logger.verbose('Shutting off webserver...');
this.shutdown().catch(console.error);
}
}, 1000);

View File

@@ -12,10 +12,13 @@ import * as azureResourceUtils from './azureResource/utils';
import * as constants from './constants';
import * as loc from './localizedConstants';
import * as utils from './utils';
import { Logger } from './utils/Logger';
const typesClause = [
azureResource.AzureResourceType.sqlDatabase,
azureResource.AzureResourceType.sqlServer,
azureResource.AzureResourceType.sqlSynapseWorkspace,
azureResource.AzureResourceType.sqlSynapseSqlPool,
azureResource.AzureResourceType.sqlManagedInstance,
azureResource.AzureResourceType.postgresServer,
azureResource.AzureResourceType.azureArcService,
@@ -24,13 +27,15 @@ const typesClause = [
].map(type => `type == "${type}"`).join(' or ');
export class AzureDataGridProvider implements azdata.DataGridProvider {
constructor(private _appContext: AppContext) { }
constructor(private _appContext: AppContext,
private readonly authLibrary: string) { }
public providerId = constants.dataGridProviderId;
public title = loc.azureResourcesGridTitle;
public async getDataGridItems() {
const accounts = await azdata.accounts.getAllAccounts();
let accounts: azdata.Account[];
accounts = azureResourceUtils.filterAccounts(await azdata.accounts.getAllAccounts(), this.authLibrary);
const items: any[] = [];
await Promise.all(accounts.map(async (account) => {
await Promise.all(account.properties.tenants.map(async (tenant: { id: string; }) => {
@@ -56,10 +61,10 @@ export class AzureDataGridProvider implements azdata.DataGridProvider {
});
items.push(...newItems);
} catch (err) {
console.log(err);
Logger.error(err);
}
} catch (err) {
console.log(err);
Logger.error(err);
}
}));
}));

View File

@@ -17,9 +17,9 @@ import { AzureResourceServiceNames } from './constants';
import { AzureAccount, Tenant, azureResource } from 'azurecore';
import { FlatAccountTreeNode } from './tree/flatAccountTreeNode';
import { ConnectionDialogTreeProvider } from './tree/connectionDialogTreeProvider';
import { AzureResourceErrorMessageUtil } from './utils';
import { AzureResourceErrorMessageUtil, filterAccounts } from './utils';
export function registerAzureResourceCommands(appContext: AppContext, azureViewTree: AzureResourceTreeProvider, connectionDialogTree: ConnectionDialogTreeProvider): void {
export function registerAzureResourceCommands(appContext: AppContext, azureViewTree: AzureResourceTreeProvider, connectionDialogTree: ConnectionDialogTreeProvider, authLibrary: string): void {
const trees = [azureViewTree, connectionDialogTree];
vscode.commands.registerCommand('azure.resource.startterminal', async (node?: TreeNode) => {
try {
@@ -33,7 +33,7 @@ export function registerAzureResourceCommands(appContext: AppContext, azureViewT
if (node instanceof AzureResourceAccountTreeNode) {
azureAccount = node.account;
} else {
let accounts = await azdata.accounts.getAllAccounts();
let accounts = filterAccounts(await azdata.accounts.getAllAccounts(), authLibrary);
accounts = accounts.filter(a => a.key.providerId.startsWith('azure'));
if (accounts.length === 0) {
const signin = localize('azure.signIn', "Sign in");

View File

@@ -10,6 +10,10 @@ export enum AzureResourceItemType {
database = 'azure.resource.itemType.database',
databaseServerContainer = 'azure.resource.itemType.databaseServerContainer',
databaseServer = 'azure.resource.itemType.databaseServer',
synapseSqlPoolContainer = 'azure.resource.itemType.synapseSqlPoolContainer',
synapseSqlPool = 'azure.resource.itemType.synapseSqlPool',
synapseWorkspaceContainer = 'azure.resource.itemType.synapseWorkspaceContainer',
synapseWorkspace = 'azure.resource.itemType.synapseWorkspace',
azureDataExplorerContainer = 'azure.resource.itemType.azureDataExplorerContainer',
azureDataExplorer = 'azure.resource.itemType.azureDataExplorer',
sqlInstance = 'azure.resource.itemType.sqlInstance',
@@ -29,3 +33,5 @@ export enum AzureResourceServiceNames {
tenantService = 'AzureResourceTenantService',
terminalService = 'AzureTerminalService',
}
export const mssqlProvider = 'MSSQL';

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { azureResource } from 'azurecore';
import { logAnalyticsQuery } from '../queryStringConstants';
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
export interface AzureMonitorGraphData extends GraphData {
@@ -15,12 +16,10 @@ export interface AzureMonitorGraphData extends GraphData {
};
}
const instanceQuery = `where type == "${azureResource.AzureResourceType.logAnalytics}"`;
export class AzureMonitorResourceService extends ResourceServiceBase<AzureMonitorGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return instanceQuery;
return logAnalyticsQuery;
}
protected convertResource(resource: AzureMonitorGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -6,6 +6,7 @@
import { ResourceServiceBase, GraphData } from '../../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore';
import { cosmosMongoDbQuery } from '../../queryStringConstants';
interface DbServerGraphData extends GraphData {
@@ -15,12 +16,10 @@ interface DbServerGraphData extends GraphData {
};
}
const serversQuery = `where type == "${azureResource.AzureResourceType.cosmosDbAccount}" and kind == "MongoDB"`;
export class CosmosDbMongoService extends ResourceServiceBase<DbServerGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return serversQuery;
return cosmosMongoDbQuery;
}
protected convertResource(resource: DbServerGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode';
import { azureResource } from 'azurecore';

View File

@@ -5,8 +5,8 @@
import { ServiceClientCredentials } from '@azure/ms-rest-js';
import { IAzureResourceService } from '../../interfaces';
import { DbServerGraphData, SynapseWorkspaceGraphData } from '../databaseServer/databaseServerService';
import { synapseWorkspacesQuery, sqlServersQuery } from '../databaseServer/serverQueryStrings';
import { DbServerGraphData } from '../databaseServer/databaseServerService';
import { sqlServerQuery, sqlDatabaseQuery } from '../queryStringConstants';
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
import { queryGraphResources, GraphData } from '../resourceTreeDataProviderBase';
import { AzureAccount, azureResource } from 'azurecore';
@@ -19,69 +19,43 @@ export class AzureResourceDatabaseService implements IAzureResourceService<azure
const databases: azureResource.AzureResourceDatabase[] = [];
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
// Query servers, synapse workspaces, and databases in parallel (start all promises before waiting on the 1st)
let servers: DbServerGraphData[];
let synapseWorkspaces: SynapseWorkspaceGraphData[];
let combined: (DbServerGraphData | SynapseWorkspaceGraphData)[] = [];
/**
* We need to get the list of servers minus the Synapse Workspaces,
* then we need to make another query to get them.
*
* This is done because the first query provides invalid endpoints for Synapse Workspaces
* While the second one provides them as one of its properties.
*
* They have to be processed in different ways as their structure differs
* in terms of properties. (See databaseServer/databaseServerService.ts for more info)
*
* Queries must be made separately due to union not being recognized by resourceGraph resource calls
*/
let synapseQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, synapseWorkspacesQuery);
let serverQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, sqlServersQuery);
let dbQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, `where type == "${azureResource.AzureResourceType.sqlDatabase}"`);
servers = await serverQueryPromise as DbServerGraphData[];
synapseWorkspaces = await synapseQueryPromise as SynapseWorkspaceGraphData[];
// Query servers and databases in parallel (start all promises before waiting on the 1st)
let serverQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, sqlServerQuery);
let dbQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, sqlDatabaseQuery);
let servers: DbServerGraphData[] = await serverQueryPromise as DbServerGraphData[];
let dbByGraph: DatabaseGraphData[] = await dbQueryPromise as DatabaseGraphData[];
combined = combined.concat(servers).concat(synapseWorkspaces);
// Group servers by resource group, then merge DB results with servers so we
// can get the login name and server fully qualified name to use for connections
let rgMap = new Map<string, (DbServerGraphData | SynapseWorkspaceGraphData)[]>();
combined.forEach(s => {
if ((s as SynapseWorkspaceGraphData).properties.connectivityEndpoints) {
// If the resource is a Synapse Workspace, we need to use the managedResourceGroupName
// (any SQL pools inside will use this instead of the regular resource group associated with the workspace itself).
let serversForRg = rgMap.get((s as SynapseWorkspaceGraphData).properties.managedResourceGroupName) || [];
serversForRg.push(s as SynapseWorkspaceGraphData);
rgMap.set((s as SynapseWorkspaceGraphData).properties.managedResourceGroupName, serversForRg);
} else {
let serversForRg = rgMap.get(s.resourceGroup) || [];
serversForRg.push(s);
rgMap.set(s.resourceGroup, serversForRg);
}
let rgMap = new Map<string, (DbServerGraphData)[]>();
servers.forEach(s => {
let serversForRg = rgMap.get(s.resourceGroup) || [];
serversForRg.push(s);
rgMap.set(s.resourceGroup, serversForRg);
});
// Match database ID. When calling exec [0] is full match, [1] is resource group name, [2] is server name
const svrIdRegExp = new RegExp(`\/subscriptions\/.+\/resourceGroups\/(.+)\/providers\/Microsoft\.Sql\/servers\/(.+)\/databases\/.+`);
const synapseDBRegExp = new RegExp(`\/subscriptions\/.+\/resourceGroups\/(.+)\/providers\/Microsoft\.Synapse\/workspaces\/(.+)\/databases\/.+`);
dbByGraph.forEach(db => {
// Filter master DBs, and for all others find their server to get login info
let serversForRg = rgMap.get(db.resourceGroup);
if (serversForRg && !db.kind.endsWith('system') && svrIdRegExp.test(db.id)) {
const founds = svrIdRegExp.exec(db.id);
if (serversForRg && !db.kind.endsWith('system') && (svrIdRegExp.test(db.id) || synapseDBRegExp.test(db.id))) {
const founds = svrIdRegExp.exec(db.id) ?? synapseDBRegExp.exec(db.id);
if (!founds) {
console.warn(`Could not parse server name from ID ${db.id}`);
return;
}
const serverName = founds[2];
let server = combined.find(s => s.name === serverName);
let server = servers.find(s => s.name === serverName);
if (server) {
databases.push({
name: db.name,
id: db.id,
serverName: server.name,
// Determine if server object is for Synapse Workspace or not and get the needed property from the correct place.
serverFullName: (server as SynapseWorkspaceGraphData).properties.connectivityEndpoints?.sql ?? (server as DbServerGraphData).properties.fullyQualifiedDomainName,
loginName: (server as SynapseWorkspaceGraphData).properties.sqlAdministratorLogin ?? (server as DbServerGraphData).properties.administratorLogin,
serverFullName: server.properties.fullyQualifiedDomainName,
loginName: server.properties.administratorLogin,
subscription: {
id: db.subscriptionId,
name: (subscriptions.find(sub => sub.id === db.subscriptionId))?.name || ''

View File

@@ -8,7 +8,7 @@ import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { AzureResourceItemType } from '../../../azureResource/constants';
import { AzureResourceItemType, mssqlProvider } from '../../../azureResource/constants';
import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
@@ -25,6 +25,7 @@ export class AzureResourceDatabaseTreeDataProvider extends ResourceTreeDataProvi
) {
super(databaseService);
}
protected getTreeItemForResource(database: azureResource.AzureResourceDatabase, account: AzureAccount): TreeItem {
return {
id: `databaseServer_${database.serverFullName}.database_${database.name}`,
@@ -46,7 +47,7 @@ export class AzureResourceDatabaseTreeDataProvider extends ResourceTreeDataProvi
savePassword: true,
groupFullName: '',
groupId: '',
providerName: 'MSSQL',
providerName: mssqlProvider,
saveProfile: false,
options: {},
azureAccount: account.key.accountId,
@@ -54,7 +55,7 @@ export class AzureResourceDatabaseTreeDataProvider extends ResourceTreeDataProvi
azureTenantId: database.tenant,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint
},
childProvider: 'MSSQL',
childProvider: mssqlProvider,
type: ExtensionNodeType.Database
};
}

View File

@@ -6,8 +6,8 @@
import { ServiceClientCredentials } from '@azure/ms-rest-js';
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
import { GraphData, queryGraphResources } from '../resourceTreeDataProviderBase';
import { sqlServerQuery } from '../queryStringConstants';
import { azureResource, AzureAccount } from 'azurecore';
import { sqlServersQuery, synapseWorkspacesQuery } from './serverQueryStrings';
import { IAzureResourceService } from '../../interfaces';
export interface DbServerGraphData extends GraphData {
@@ -17,54 +17,14 @@ export interface DbServerGraphData extends GraphData {
};
}
/**
* Properties returned by the Synapse query are different from the server ones and have to be treated differently.
*/
export interface SynapseWorkspaceGraphData extends GraphData {
properties: {
/**
* SQL connectivity endpoint and other endpoints are found here, instead of fullyQualifiedDomainName.
*/
connectivityEndpoints: { sql: string };
/**
* managedResourceGroupName is the resource group used by any SQL pools inside the workspace
* which is different from the resource group of the workspace itself.
*/
managedResourceGroupName: string;
/**
* administratorLogin is called sqlAdministratorLogin here.
*/
sqlAdministratorLogin: string;
};
}
export class AzureResourceDatabaseServerService implements IAzureResourceService<azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return sqlServersQuery;
}
public async getResources(subscriptions: azureResource.AzureResourceSubscription[], credential: ServiceClientCredentials, account: AzureAccount): Promise<azureResource.AzureResourceDatabaseServer[]> {
const convertedResources: azureResource.AzureResourceDatabaseServer[] = [];
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
/**
* We need to get the list of servers minus the Synapse Workspaces,
* then we need to make another query to get them.
*
* This is done because the first query provides invalid endpoints for Synapse Workspaces
* While the second one provides them as one of its properties.
*
* They have to be processed in different ways by convertResource as their structure differs
* in terms of properties. (See above)
*
* Queries must be made separately due to union not being recognized by resourceGraph resource calls.
*/
let combinedGraphResources: (DbServerGraphData | SynapseWorkspaceGraphData)[] = [];
let serverGraphResources: DbServerGraphData[] = await queryGraphResources<DbServerGraphData>(resourceClient, subscriptions, this.query);
let synapseGraphResources: SynapseWorkspaceGraphData[] = await queryGraphResources<SynapseWorkspaceGraphData>(resourceClient, subscriptions, synapseWorkspacesQuery);
combinedGraphResources = combinedGraphResources.concat(serverGraphResources).concat(synapseGraphResources);
let serverGraphResources: DbServerGraphData[] = await queryGraphResources<DbServerGraphData>(resourceClient, subscriptions, sqlServerQuery);
const ids = new Set<string>();
combinedGraphResources.forEach((res) => {
serverGraphResources.forEach((res) => {
if (!ids.has(res.id)) {
ids.add(res.id);
res.subscriptionName = subscriptions.find(sub => sub.id === res.subscriptionId)?.name;
@@ -76,14 +36,14 @@ export class AzureResourceDatabaseServerService implements IAzureResourceService
return convertedResources;
}
protected convertResource(resource: DbServerGraphData | SynapseWorkspaceGraphData): azureResource.AzureResourceDatabaseServer {
protected convertResource(resource: DbServerGraphData): azureResource.AzureResourceDatabaseServer {
return {
id: resource.id,
name: resource.name,
// Determine if resource object is for Synapse Workspace or not and get the needed property from the correct place.
fullName: (resource as SynapseWorkspaceGraphData).properties.connectivityEndpoints?.sql ?? (resource as DbServerGraphData).properties.fullyQualifiedDomainName,
loginName: (resource as SynapseWorkspaceGraphData).properties.sqlAdministratorLogin ?? (resource as DbServerGraphData).properties.administratorLogin,
fullName: resource.properties.fullyQualifiedDomainName,
loginName: resource.properties.administratorLogin,
defaultDatabaseName: 'master',
subscription: {
id: resource.subscriptionId,

View File

@@ -8,7 +8,7 @@ import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { AzureResourceItemType } from '../../../azureResource/constants';
import { AzureResourceItemType, mssqlProvider } from '../../../azureResource/constants';
import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
@@ -25,7 +25,6 @@ export class AzureResourceDatabaseServerTreeDataProvider extends ResourceTreeDat
super(databaseServerService);
}
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: AzureAccount): TreeItem {
return {
id: `databaseServer_${databaseServer.id ? databaseServer.id : databaseServer.name}`,
@@ -47,7 +46,7 @@ export class AzureResourceDatabaseServerTreeDataProvider extends ResourceTreeDat
savePassword: true,
groupFullName: '',
groupId: '',
providerName: 'MSSQL',
providerName: mssqlProvider,
saveProfile: false,
options: {},
azureAccount: account.key.accountId,
@@ -55,7 +54,7 @@ export class AzureResourceDatabaseServerTreeDataProvider extends ResourceTreeDat
azureResourceId: databaseServer.id,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint
},
childProvider: 'MSSQL',
childProvider: mssqlProvider,
type: ExtensionNodeType.Server
};
}

View File

@@ -1,18 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { azureResource } from 'azurecore';
/**
* Get list of Synapse Workspaces with information such as SQL connection endpoints.
*/
export const synapseWorkspacesQuery = `where type == "microsoft.synapse/workspaces"`;
/**
* Lists all Sql Servers except for Synapse Pool Servers
* (they have different properties and need to be handled separately,
* see databaseServerService.ts for more details)
*/
export const sqlServersQuery = `where type == "${azureResource.AzureResourceType.sqlServer}" and kind != "v12.0,analytics"`;

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { azureResource } from 'azurecore';
import { kustoClusterQuery } from '../queryStringConstants';
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
export interface KustoGraphData extends GraphData {
@@ -14,12 +15,10 @@ export interface KustoGraphData extends GraphData {
};
}
const instanceQuery = `where type == "${azureResource.AzureResourceType.kustoClusters}"`;
export class KustoResourceService extends ResourceServiceBase<KustoGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return instanceQuery;
return kustoClusterQuery;
}
protected convertResource(resource: KustoGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -6,6 +6,7 @@
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore';
import { mysqlFlexibleServerQuery } from '../queryStringConstants';
interface DbServerGraphData extends GraphData {
@@ -15,12 +16,10 @@ interface DbServerGraphData extends GraphData {
};
}
const serversQuery = `where type == "${azureResource.AzureResourceType.mysqlFlexibleServer}"`;
export class MysqlFlexibleServerService extends ResourceServiceBase<DbServerGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return serversQuery;
return mysqlFlexibleServerQuery;
}
protected convertResource(resource: DbServerGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -5,6 +5,7 @@
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore';
import { postgresArcServerQuery } from '../queryStringConstants';
export interface PostgresArcServerGraphData extends GraphData {
properties: {
@@ -12,12 +13,10 @@ export interface PostgresArcServerGraphData extends GraphData {
};
}
export const serversQuery = `where type == "${azureResource.AzureResourceType.azureArcPostgresServer}"`;
export class PostgresServerArcService extends ResourceServiceBase<PostgresArcServerGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return serversQuery;
return postgresArcServerQuery;
}
protected convertResource(resource: PostgresArcServerGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -6,7 +6,7 @@
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore';
import { postgresServerQuery } from '../queryStringConstants';
interface DbServerGraphData extends GraphData {
properties: {
@@ -15,12 +15,10 @@ interface DbServerGraphData extends GraphData {
};
}
const serversQuery = `where type == "${azureResource.AzureResourceType.postgresServer}"`;
export class PostgresServerService extends ResourceServiceBase<DbServerGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return serversQuery;
return postgresServerQuery;
}
protected convertResource(resource: DbServerGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { azureResource } from 'azurecore';
/**
* Lists all SQL Databases and Synapse SQL Databases
*/
export const sqlDatabaseQuery = `where type == "${azureResource.AzureResourceType.sqlDatabase}" or type == "${azureResource.AzureResourceType.sqlSynapseSqlDatabase}"`;
/**
* Lists all Synapse Workspaces with information such as SQL connection endpoints.
*/
export const synapseWorkspacesQuery = `where type == "${azureResource.AzureResourceType.sqlSynapseWorkspace}"`;
/**
* Lists all Synapse Dedicated SQL Pools
*/
export const synapseSqlPoolsQuery = `where type == "${azureResource.AzureResourceType.sqlSynapseSqlPool}"`;
/**
* Lists all Sql Servers excluding Synapse Pool Servers
* (they have different properties and need to be handled separately)
*/
export const sqlServerQuery = `where type == "${azureResource.AzureResourceType.sqlServer}" and kind != "v12.0,analytics"`;
/**
* Lists all Azure Arc SQL Managed Instances
*/
export const sqlInstanceArcQuery = `where type == "${azureResource.AzureResourceType.azureArcSqlManagedInstance}"`;
/**
* Lists all Azure SQL Managed Instances
*/
export const sqlInstanceQuery = `where type == "${azureResource.AzureResourceType.sqlManagedInstance}"`;
/**
* Lists all resource containers and resource groups
*/
export const resourceGroupQuery = `ResourceContainers | where type=="${azureResource.AzureResourceType.resourceGroup}"`;
/**
* Lists all postgreSQL servers
*/
export const postgresServerQuery = `where type == "${azureResource.AzureResourceType.postgresServer}"`;
/**
* Lists all Azure Arc PostgreSQL servers
*/
export const postgresArcServerQuery = `where type == "${azureResource.AzureResourceType.azureArcPostgresServer}"`;
/**
* Lists all MySQL Flexible servers
*/
export const mysqlFlexibleServerQuery = `where type == "${azureResource.AzureResourceType.mysqlFlexibleServer}"`;
/**
* Lists all Kusto Clusters
*/
export const kustoClusterQuery = `where type == "${azureResource.AzureResourceType.kustoClusters}"`;
/**
* Lists all Cosmos DB for MongoDB accounts
*/
export const cosmosMongoDbQuery = `where type == "${azureResource.AzureResourceType.cosmosDbAccount}" and kind == "MongoDB"`;
/**
* Lists all Log Analytics workspaces
*/
export const logAnalyticsQuery = `where type == "${azureResource.AzureResourceType.logAnalytics}"`;

View File

@@ -6,11 +6,12 @@
import { DbServerGraphData } from '../databaseServer/databaseServerService';
import { azureResource } from 'azurecore';
import { ResourceServiceBase } from '../resourceTreeDataProviderBase';
import { resourceGroupQuery } from '../queryStringConstants';
export class AzureResourceGroupService extends ResourceServiceBase<DbServerGraphData, azureResource.AzureResourceResourceGroup> {
protected get query(): string {
return `ResourceContainers | where type=="${azureResource.AzureResourceType.resourceGroup}"`;
return resourceGroupQuery;
}
protected convertResource(resource: DbServerGraphData): azureResource.AzureResourceResourceGroup {

View File

@@ -10,6 +10,7 @@ import { IAzureResourceService } from '../interfaces';
import { AzureResourceErrorMessageUtil } from '../utils';
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
import { AzureAccount, azureResource } from 'azurecore';
import { Logger } from '../../utils/Logger';
export abstract class ResourceTreeDataProviderBase<T extends azureResource.AzureResource> implements azureResource.IAzureResourceTreeDataProvider {
public browseConnectionMode: boolean = false;
@@ -28,17 +29,17 @@ export abstract class ResourceTreeDataProviderBase<T extends azureResource.Azure
return resources.map((resource) => <azureResource.IAzureResourceNode>{
account: element.account,
subscription: element.subscription,
tenantId: element.tenantId,
tenantId: element.subscription.tenant,
treeItem: this.getTreeItemForResource(resource, element.account)
}).sort((a, b) => (<any>a.treeItem.label).localeCompare(b.treeItem.label));
} catch (error) {
console.log(AzureResourceErrorMessageUtil.getErrorMessage(error));
Logger.error(AzureResourceErrorMessageUtil.getErrorMessage(error));
throw error;
}
}
private async getResources(element: azureResource.IAzureResourceNode): Promise<T[]> {
const response = await azdata.accounts.getAccountSecurityToken(element.account, element.tenantId, azdata.AzureResource.ResourceManagement);
const response = await azdata.accounts.getAccountSecurityToken(element.account, element.subscription.tenant!, azdata.AzureResource.ResourceManagement);
if (!response) {
throw new Error(`Did not receive security token when getting resources for account ${element.account.displayInfo.displayName}`);
}
@@ -102,7 +103,7 @@ export async function queryGraphResources<T extends GraphData>(resourceClient: R
}
} catch (err2) {
// Just log, we still want to throw the original error if something happens parsing the error
console.log(`Unexpected error while parsing error from querying resources : ${err2}`);
Logger.error(`Unexpected error while parsing error from querying resources : ${err2}`);
}
throw err;
}

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { azureResource } from 'azurecore';
import { sqlInstanceQuery } from '../queryStringConstants';
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
interface SqlInstanceGraphData extends GraphData {
@@ -13,12 +14,10 @@ interface SqlInstanceGraphData extends GraphData {
};
}
const instanceQuery = `where type == "${azureResource.AzureResourceType.sqlManagedInstance}"`;
export class SqlInstanceResourceService extends ResourceServiceBase<SqlInstanceGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return instanceQuery;
return sqlInstanceQuery;
}
protected convertResource(resource: SqlInstanceGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -8,7 +8,7 @@ import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { AzureResourceItemType } from '../../constants';
import { AzureResourceItemType, mssqlProvider } from '../../constants';
import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
@@ -47,7 +47,7 @@ export class SqlInstanceTreeDataProvider extends ResourceTreeDataProviderBase<az
savePassword: true,
groupFullName: '',
groupId: '',
providerName: 'MSSQL',
providerName: mssqlProvider,
saveProfile: false,
options: {},
azureAccount: account.key.accountId,
@@ -55,7 +55,7 @@ export class SqlInstanceTreeDataProvider extends ResourceTreeDataProviderBase<az
azureResourceId: databaseServer.id,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint
},
childProvider: 'MSSQL',
childProvider: mssqlProvider,
type: ExtensionNodeType.Server
};
}

View File

@@ -5,6 +5,7 @@
import { ResourceServiceBase, GraphData } from '../resourceTreeDataProviderBase';
import { azureResource } from 'azurecore';
import { sqlInstanceArcQuery } from '../queryStringConstants';
export interface SqlInstanceArcGraphData extends GraphData {
properties: {
@@ -13,11 +14,10 @@ export interface SqlInstanceArcGraphData extends GraphData {
};
}
const instanceQuery = `where type == "${azureResource.AzureResourceType.azureArcSqlManagedInstance}"`;
export class SqlInstanceArcResourceService extends ResourceServiceBase<SqlInstanceArcGraphData, azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return instanceQuery;
return sqlInstanceArcQuery;
}
protected convertResource(resource: SqlInstanceArcGraphData): azureResource.AzureResourceDatabaseServer {

View File

@@ -8,7 +8,7 @@ import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { AzureResourceItemType } from '../../constants';
import { AzureResourceItemType, mssqlProvider } from '../../constants';
import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
@@ -48,7 +48,7 @@ export class SqlInstanceArcTreeDataProvider extends ResourceTreeDataProviderBase
savePassword: true,
groupFullName: '',
groupId: '',
providerName: 'MSSQL',
providerName: mssqlProvider,
saveProfile: false,
options: {},
azureAccount: account.key.accountId,
@@ -56,7 +56,7 @@ export class SqlInstanceArcTreeDataProvider extends ResourceTreeDataProviderBase
azureResourceId: databaseServer.id,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint
},
childProvider: 'MSSQL',
childProvider: mssqlProvider,
type: ExtensionNodeType.Server
};
}

View File

@@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode';
import { azureResource } from 'azurecore';
import { AzureResourceSynapseSqlPoolTreeDataProvider as AzureResourceSynapseSqlPoolTreeDataProvider } from './synapseSqlPoolTreeDataProvider';
import { IAzureResourceService } from '../../interfaces';
export class AzureResourceSynapseSqlPoolProvider implements azureResource.IAzureResourceProvider {
public constructor(
private _synapseSqlPoolService: IAzureResourceService<azureResource.AzureResourceDatabase>,
private _extensionContext: ExtensionContext
) {
}
public getTreeDataProvider(): azureResource.IAzureResourceTreeDataProvider {
return new AzureResourceSynapseSqlPoolTreeDataProvider(this._synapseSqlPoolService, this._extensionContext);
}
public get providerId(): string {
return 'azure.resource.providers.synapseSqlPool';
}
}

View File

@@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ServiceClientCredentials } from '@azure/ms-rest-js';
import { IAzureResourceService } from '../../interfaces';
import { SynapseWorkspaceGraphData } from '../synapseWorkspace/synapseWorkspaceService';
import { synapseWorkspacesQuery, synapseSqlPoolsQuery } from '../queryStringConstants';
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
import { queryGraphResources, GraphData } from '../resourceTreeDataProviderBase';
import { AzureAccount, azureResource } from 'azurecore';
interface SynapseGraphData extends GraphData {
kind: string;
}
export class AzureResourceSynapseService implements IAzureResourceService<azureResource.AzureResourceDatabase> {
public async getResources(subscriptions: azureResource.AzureResourceSubscription[], credential: ServiceClientCredentials, account: AzureAccount): Promise<azureResource.AzureResourceDatabase[]> {
const databases: azureResource.AzureResourceDatabase[] = [];
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
// Query synapse servers, and databases in parallel (start all promises before waiting on the 1st)
let synapseQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, synapseSqlPoolsQuery);
let synapseWorkspaceQueryPromise = queryGraphResources<GraphData>(resourceClient, subscriptions, synapseWorkspacesQuery);
let synapse = await synapseQueryPromise as SynapseGraphData[];
let synapseWorkspaceByGraph: SynapseWorkspaceGraphData[] = await synapseWorkspaceQueryPromise as SynapseWorkspaceGraphData[];
// Group servers by resource group, then merge DB results with servers so we
// can get the login name and server fully qualified name to use for connections
let rgMap = new Map<string, SynapseWorkspaceGraphData[]>();
synapseWorkspaceByGraph.forEach(s => {
// As the resource is a Synapse Workspace, we need to use the managedResourceGroupName
// (any SQL pools inside will use this instead of the regular resource group associated with the workspace itself).
let serversForRg = rgMap.get(s.properties.managedResourceGroupName) || [];
serversForRg.push(s);
rgMap.set(s.properties.managedResourceGroupName, serversForRg);
});
// Match database ID. When calling exec [0] is full match, [1] is resource group name, [2] is server name
const svrIdRegExp = new RegExp(`\/subscriptions\/.+\/resourceGroups\/(.+)\/providers\/Microsoft\.Synapse\/workspaces\/(.+)\/sqlPools\/.+`);
synapse.forEach(db => {
// Filter master DBs, and for all others find their server to get login info
if (!db.kind.endsWith('system') && svrIdRegExp.test(db.id)) {
const founds = svrIdRegExp.exec(db.id);
if (!founds) {
console.warn(`Could not parse server name from ID ${db.id}`);
return;
}
const serverName = founds[2];
let server = synapseWorkspaceByGraph.find(s => s.name === serverName);
if (server) {
databases.push({
name: db.name,
id: db.id,
serverName: server.name,
serverFullName: server.properties.connectivityEndpoints?.sql,
loginName: server.properties.sqlAdministratorLogin,
subscription: {
id: db.subscriptionId,
name: (subscriptions.find(sub => sub.id === db.subscriptionId))?.name || ''
},
tenant: db.tenantId,
resourceGroup: db.resourceGroup
});
}
}
});
return databases;
}
}

View File

@@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TreeItem, ExtensionNodeType } from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { AzureResourceItemType, mssqlProvider } from '../../constants';
import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
import { AzureAccount, azureResource } from 'azurecore';
export class AzureResourceSynapseSqlPoolTreeDataProvider extends ResourceTreeDataProviderBase<azureResource.AzureResourceDatabase> {
private static readonly containerId = 'azure.resource.providers.synapseSqlPool.treeDataProvider.synapseSqlPoolContainer';
private static readonly containerLabel = localize('azure.resource.providers.synapseSqlPool.treeDataProvider.synapseSqlPoolContainerLabel', "Dedicated SQL Pools");
public constructor(
synapseSqlPoolService: IAzureResourceService<azureResource.AzureResourceDatabase>,
private _extensionContext: vscode.ExtensionContext
) {
super(synapseSqlPoolService);
}
protected getTreeItemForResource(synapse: azureResource.AzureResourceDatabase, account: AzureAccount): TreeItem {
return {
id: `synapseWorkspace_${synapse.serverFullName}.synapseSqlPool_${synapse.name}`,
label: this.browseConnectionMode ? `${synapse.serverName}/${synapse.name} (${AzureResourceSynapseSqlPoolTreeDataProvider.containerLabel}, ${synapse.subscription.name})` : `${synapse.name} (${synapse.serverName})`,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/sql_database_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/sql_database.svg')
},
collapsibleState: this.browseConnectionMode ? vscode.TreeItemCollapsibleState.None : vscode.TreeItemCollapsibleState.Collapsed,
contextValue: AzureResourceItemType.synapseSqlPool,
payload: {
id: generateGuid(),
connectionName: undefined,
serverName: synapse.serverFullName,
databaseName: synapse.name,
userName: synapse.loginName,
password: '',
authenticationType: '',
savePassword: true,
groupFullName: '',
groupId: '',
providerName: mssqlProvider,
saveProfile: false,
options: {},
azureAccount: account.key.accountId,
azureResourceId: synapse.id,
azureTenantId: synapse.tenant,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint
},
childProvider: mssqlProvider,
type: ExtensionNodeType.Database
};
}
public async getRootChildren(): Promise<TreeItem[]> {
return [{
id: AzureResourceSynapseSqlPoolTreeDataProvider.containerId,
label: AzureResourceSynapseSqlPoolTreeDataProvider.containerLabel,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/folder.svg')
},
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextValue: AzureResourceItemType.synapseSqlPoolContainer
}];
}
}

View File

@@ -0,0 +1,26 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode';
import { azureResource } from 'azurecore';
import { AzureResourceSynapseWorkspaceTreeDataProvider } from './synapseWorkspaceTreeDataProvider';
import { IAzureResourceService } from '../../interfaces';
export class AzureResourceSynapseWorkspaceProvider implements azureResource.IAzureResourceProvider {
public constructor(
private _synapseWorkspaceService: IAzureResourceService<azureResource.AzureResourceDatabaseServer>,
private _extensionContext: ExtensionContext
) {
}
public getTreeDataProvider(): azureResource.IAzureResourceTreeDataProvider {
return new AzureResourceSynapseWorkspaceTreeDataProvider(this._synapseWorkspaceService, this._extensionContext);
}
public get providerId(): string {
return 'azure.resource.providers.synapseWorkspace';
}
}

View File

@@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ServiceClientCredentials } from '@azure/ms-rest-js';
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
import { GraphData, queryGraphResources } from '../resourceTreeDataProviderBase';
import { azureResource, AzureAccount } from 'azurecore';
import { IAzureResourceService } from '../../interfaces';
import { synapseWorkspacesQuery } from '../queryStringConstants';
/**
* Properties returned by the Synapse query are different from the server ones and have to be treated differently.
*/
export interface SynapseWorkspaceGraphData extends GraphData {
properties: {
/**
* SQL connectivity endpoint and other endpoints are found here, instead of fullyQualifiedDomainName.
*/
connectivityEndpoints: { sql: string };
/**
* managedResourceGroupName is the resource group used by any SQL pools inside the workspace
* which is different from the resource group of the workspace itself.
*/
managedResourceGroupName: string;
/**
* administratorLogin is called sqlAdministratorLogin here.
*/
sqlAdministratorLogin: string;
};
}
export class AzureResourceSynapseWorkspaceService implements IAzureResourceService<azureResource.AzureResourceDatabaseServer> {
protected get query(): string {
return synapseWorkspacesQuery;
}
public async getResources(subscriptions: azureResource.AzureResourceSubscription[], credential: ServiceClientCredentials, account: AzureAccount): Promise<azureResource.AzureResourceDatabaseServer[]> {
const convertedResources: azureResource.AzureResourceDatabaseServer[] = [];
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
let serverGraphResources: SynapseWorkspaceGraphData[] = await queryGraphResources<SynapseWorkspaceGraphData>(resourceClient, subscriptions, this.query);
const ids = new Set<string>();
serverGraphResources.forEach((res) => {
if (!ids.has(res.id)) {
ids.add(res.id);
res.subscriptionName = subscriptions.find(sub => sub.id === res.subscriptionId)?.name;
const converted = this.convertResource(res);
convertedResources.push(converted);
}
});
return convertedResources;
}
protected convertResource(resource: SynapseWorkspaceGraphData): azureResource.AzureResourceDatabaseServer {
return {
id: resource.id,
name: resource.name,
fullName: resource.properties.connectivityEndpoints?.sql,
loginName: resource.properties.sqlAdministratorLogin,
defaultDatabaseName: 'master',
subscription: {
id: resource.subscriptionId,
name: resource.subscriptionName || ''
},
tenant: resource.tenantId,
resourceGroup: resource.resourceGroup
};
}
}

View File

@@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionNodeType, TreeItem } from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { AzureResourceItemType, mssqlProvider } from '../../constants';
import { generateGuid } from '../../utils';
import { IAzureResourceService } from '../../interfaces';
import { ResourceTreeDataProviderBase } from '../resourceTreeDataProviderBase';
import { AzureAccount, azureResource } from 'azurecore';
export class AzureResourceSynapseWorkspaceTreeDataProvider extends ResourceTreeDataProviderBase<azureResource.AzureResourceDatabaseServer> {
private static readonly containerId = 'azure.resource.providers.synapseWorkspace.treeDataProvider.synapseWorkspaceContainer';
private static readonly containerLabel = localize('azure.resource.providers.synapseWorkspace.treeDataProvider.synapseWorkspaceContainerLabel', "Azure Synapse Analytics");
public constructor(
synapseWorkspaceService: IAzureResourceService<azureResource.AzureResourceDatabaseServer>,
private _extensionContext: vscode.ExtensionContext
) {
super(synapseWorkspaceService);
}
protected getTreeItemForResource(synapseWorkspace: azureResource.AzureResourceDatabaseServer, account: AzureAccount): TreeItem {
return {
id: `synapseWorkspace_${synapseWorkspace.id ?? synapseWorkspace.name}`,
label: this.browseConnectionMode ? `${synapseWorkspace.name} (${AzureResourceSynapseWorkspaceTreeDataProvider.containerLabel}, ${synapseWorkspace.subscription.name})` : synapseWorkspace.name,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/sql_server_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/sql_server.svg')
},
collapsibleState: this.browseConnectionMode ? vscode.TreeItemCollapsibleState.None : vscode.TreeItemCollapsibleState.Collapsed,
contextValue: AzureResourceItemType.synapseWorkspace,
payload: {
id: generateGuid(),
connectionName: undefined,
serverName: synapseWorkspace.fullName,
databaseName: synapseWorkspace.defaultDatabaseName,
userName: synapseWorkspace.loginName,
password: '',
authenticationType: '',
savePassword: true,
groupFullName: '',
groupId: '',
providerName: mssqlProvider,
saveProfile: false,
options: {},
azureAccount: account.key.accountId,
azureTenantId: synapseWorkspace.tenant,
azureResourceId: synapseWorkspace.id,
azurePortalEndpoint: account.properties.providerSettings.settings.portalEndpoint
},
childProvider: mssqlProvider,
type: ExtensionNodeType.Server
};
}
public async getRootChildren(): Promise<TreeItem[]> {
return [{
id: AzureResourceSynapseWorkspaceTreeDataProvider.containerId,
label: AzureResourceSynapseWorkspaceTreeDataProvider.containerLabel,
iconPath: {
dark: this._extensionContext.asAbsolutePath('resources/dark/folder_inverse.svg'),
light: this._extensionContext.asAbsolutePath('resources/light/folder.svg')
},
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextValue: AzureResourceItemType.synapseWorkspaceContainer
}];
}
}

Some files were not shown because too many files have changed in this diff Show More