@microsoft/teamsfx-core 1.6.1 → 1.6.2-alpha.6399c5efb.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/common/constants.d.ts +3 -0
- package/build/common/constants.d.ts.map +1 -1
- package/build/common/constants.js +3 -0
- package/build/common/constants.js.map +1 -1
- package/build/common/local/localEnvManager.d.ts +5 -2
- package/build/common/local/localEnvManager.d.ts.map +1 -1
- package/build/common/local/localEnvManager.js +16 -2
- package/build/common/local/localEnvManager.js.map +1 -1
- package/build/common/local/localStateHelper.d.ts +3 -0
- package/build/common/local/localStateHelper.d.ts.map +1 -0
- package/build/common/local/localStateHelper.js +133 -0
- package/build/common/local/localStateHelper.js.map +1 -0
- package/build/common/local/taskDefinition.d.ts +3 -0
- package/build/common/local/taskDefinition.d.ts.map +1 -1
- package/build/common/local/taskDefinition.js +36 -0
- package/build/common/local/taskDefinition.js.map +1 -1
- package/build/common/localStateConstants.d.ts +39 -0
- package/build/common/localStateConstants.d.ts.map +1 -0
- package/build/common/localStateConstants.js +44 -0
- package/build/common/localStateConstants.js.map +1 -0
- package/build/common/localStateProvider.d.ts +7 -0
- package/build/common/localStateProvider.d.ts.map +1 -0
- package/build/common/localStateProvider.js +28 -0
- package/build/common/localStateProvider.js.map +1 -0
- package/build/common/projectSettingsHelper.d.ts.map +1 -1
- package/build/common/projectSettingsHelper.js +2 -0
- package/build/common/projectSettingsHelper.js.map +1 -1
- package/build/common/samples-config.json +2 -2
- package/build/common/telemetry.d.ts +26 -0
- package/build/common/telemetry.d.ts.map +1 -1
- package/build/common/telemetry.js +26 -0
- package/build/common/telemetry.js.map +1 -1
- package/build/common/template-utils/templatesActions.d.ts +2 -2
- package/build/common/template-utils/templatesActions.d.ts.map +1 -1
- package/build/common/template-utils/templatesActions.js +6 -6
- package/build/common/template-utils/templatesActions.js.map +1 -1
- package/build/common/templates-config.json +4 -3
- package/build/common/tools.d.ts +4 -0
- package/build/common/tools.d.ts.map +1 -1
- package/build/common/tools.js +27 -1
- package/build/common/tools.js.map +1 -1
- package/build/core/FxCore.d.ts +2 -0
- package/build/core/FxCore.d.ts.map +1 -1
- package/build/core/FxCore.js +122 -6
- package/build/core/FxCore.js.map +1 -1
- package/build/core/environment.d.ts +1 -0
- package/build/core/environment.d.ts.map +1 -1
- package/build/core/environment.js +9 -2
- package/build/core/environment.js.map +1 -1
- package/build/core/error.d.ts +5 -0
- package/build/core/error.d.ts.map +1 -1
- package/build/core/error.js +21 -1
- package/build/core/error.js.map +1 -1
- package/build/core/globalVars.d.ts +4 -0
- package/build/core/globalVars.d.ts.map +1 -1
- package/build/core/globalVars.js +5 -1
- package/build/core/globalVars.js.map +1 -1
- package/build/core/middleware/aadManifestMigration.d.ts +3 -0
- package/build/core/middleware/aadManifestMigration.d.ts.map +1 -0
- package/build/core/middleware/aadManifestMigration.js +186 -0
- package/build/core/middleware/aadManifestMigration.js.map +1 -0
- package/build/core/middleware/consolidateLocalRemote.d.ts +5 -0
- package/build/core/middleware/consolidateLocalRemote.d.ts.map +1 -0
- package/build/core/middleware/consolidateLocalRemote.js +204 -0
- package/build/core/middleware/consolidateLocalRemote.js.map +1 -0
- package/build/core/middleware/envInfoLoader.d.ts.map +1 -1
- package/build/core/middleware/envInfoLoader.js +6 -14
- package/build/core/middleware/envInfoLoader.js.map +1 -1
- package/build/core/middleware/envInfoWriter.d.ts.map +1 -1
- package/build/core/middleware/envInfoWriter.js +6 -0
- package/build/core/middleware/envInfoWriter.js.map +1 -1
- package/build/core/middleware/projectMigrator.d.ts +3 -0
- package/build/core/middleware/projectMigrator.d.ts.map +1 -1
- package/build/core/middleware/projectMigrator.js +3 -1
- package/build/core/middleware/projectMigrator.js.map +1 -1
- package/build/core/middleware/questionModel.d.ts.map +1 -1
- package/build/core/middleware/questionModel.js +55 -1
- package/build/core/middleware/questionModel.js.map +1 -1
- package/build/core/question.d.ts +13 -2
- package/build/core/question.d.ts.map +1 -1
- package/build/core/question.js +153 -61
- package/build/core/question.js.map +1 -1
- package/build/plugins/resource/aad/aadAppClient.d.ts +4 -0
- package/build/plugins/resource/aad/aadAppClient.d.ts.map +1 -1
- package/build/plugins/resource/aad/aadAppClient.js +52 -0
- package/build/plugins/resource/aad/aadAppClient.js.map +1 -1
- package/build/plugins/resource/aad/aadAppManifestManager.d.ts +11 -0
- package/build/plugins/resource/aad/aadAppManifestManager.d.ts.map +1 -0
- package/build/plugins/resource/aad/aadAppManifestManager.js +117 -0
- package/build/plugins/resource/aad/aadAppManifestManager.js.map +1 -0
- package/build/plugins/resource/aad/constants.d.ts +13 -0
- package/build/plugins/resource/aad/constants.d.ts.map +1 -1
- package/build/plugins/resource/aad/constants.js +25 -0
- package/build/plugins/resource/aad/constants.js.map +1 -1
- package/build/plugins/resource/aad/errors.d.ts +21 -0
- package/build/plugins/resource/aad/errors.d.ts.map +1 -1
- package/build/plugins/resource/aad/errors.js +65 -1
- package/build/plugins/resource/aad/errors.js.map +1 -1
- package/build/plugins/resource/aad/index.d.ts +3 -0
- package/build/plugins/resource/aad/index.d.ts.map +1 -1
- package/build/plugins/resource/aad/index.js +9 -1
- package/build/plugins/resource/aad/index.js.map +1 -1
- package/build/plugins/resource/aad/interfaces/AADApplication.d.ts +2 -3
- package/build/plugins/resource/aad/interfaces/AADApplication.d.ts.map +1 -1
- package/build/plugins/resource/aad/interfaces/AADManifest.d.ts +2 -3
- package/build/plugins/resource/aad/interfaces/AADManifest.d.ts.map +1 -1
- package/build/plugins/resource/aad/permissions/index.d.ts +1 -0
- package/build/plugins/resource/aad/permissions/index.d.ts.map +1 -1
- package/build/plugins/resource/aad/permissions/index.js +27 -1
- package/build/plugins/resource/aad/permissions/index.js.map +1 -1
- package/build/plugins/resource/aad/permissions/permissions.json +1084 -204
- package/build/plugins/resource/aad/plugin.d.ts +6 -1
- package/build/plugins/resource/aad/plugin.d.ts.map +1 -1
- package/build/plugins/resource/aad/plugin.js +117 -20
- package/build/plugins/resource/aad/plugin.js.map +1 -1
- package/build/plugins/resource/aad/utils/aadManifestHelper.d.ts +2 -0
- package/build/plugins/resource/aad/utils/aadManifestHelper.d.ts.map +1 -1
- package/build/plugins/resource/aad/utils/aadManifestHelper.js +84 -8
- package/build/plugins/resource/aad/utils/aadManifestHelper.js.map +1 -1
- package/build/plugins/resource/aad/utils/configs.d.ts +3 -1
- package/build/plugins/resource/aad/utils/configs.d.ts.map +1 -1
- package/build/plugins/resource/aad/utils/configs.js +6 -3
- package/build/plugins/resource/aad/utils/configs.js.map +1 -1
- package/build/plugins/resource/aad/v2/index.d.ts +3 -1
- package/build/plugins/resource/aad/v2/index.d.ts.map +1 -1
- package/build/plugins/resource/aad/v2/index.js +6 -0
- package/build/plugins/resource/aad/v2/index.js.map +1 -1
- package/build/plugins/resource/apiconnector/constants.d.ts +28 -0
- package/build/plugins/resource/apiconnector/constants.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/constants.js +37 -0
- package/build/plugins/resource/apiconnector/constants.js.map +1 -0
- package/build/plugins/resource/apiconnector/envHandler.d.ts +18 -0
- package/build/plugins/resource/apiconnector/envHandler.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/envHandler.js +88 -0
- package/build/plugins/resource/apiconnector/envHandler.js.map +1 -0
- package/build/plugins/resource/apiconnector/errors.d.ts +39 -0
- package/build/plugins/resource/apiconnector/errors.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/errors.js +46 -0
- package/build/plugins/resource/apiconnector/errors.js.map +1 -0
- package/build/plugins/resource/apiconnector/index.d.ts +14 -0
- package/build/plugins/resource/apiconnector/index.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/index.js +43 -0
- package/build/plugins/resource/apiconnector/index.js.map +1 -0
- package/build/plugins/resource/apiconnector/plugin.d.ts +14 -0
- package/build/plugins/resource/apiconnector/plugin.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/plugin.js +138 -0
- package/build/plugins/resource/apiconnector/plugin.js.map +1 -0
- package/build/plugins/resource/apiconnector/questions.d.ts +13 -0
- package/build/plugins/resource/apiconnector/questions.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/questions.js +63 -0
- package/build/plugins/resource/apiconnector/questions.js.map +1 -0
- package/build/plugins/resource/apiconnector/result.d.ts +9 -0
- package/build/plugins/resource/apiconnector/result.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/result.js +21 -0
- package/build/plugins/resource/apiconnector/result.js.map +1 -0
- package/build/plugins/resource/apiconnector/sampleHandler.d.ts +10 -0
- package/build/plugins/resource/apiconnector/sampleHandler.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/sampleHandler.js +47 -0
- package/build/plugins/resource/apiconnector/sampleHandler.js.map +1 -0
- package/build/plugins/resource/apiconnector/utils.d.ts +26 -0
- package/build/plugins/resource/apiconnector/utils.d.ts.map +1 -0
- package/build/plugins/resource/apiconnector/utils.js +47 -0
- package/build/plugins/resource/apiconnector/utils.js.map +1 -0
- package/build/plugins/resource/appstudio/constants.d.ts +4 -0
- package/build/plugins/resource/appstudio/constants.d.ts.map +1 -1
- package/build/plugins/resource/appstudio/constants.js +30 -1
- package/build/plugins/resource/appstudio/constants.js.map +1 -1
- package/build/plugins/resource/appstudio/manifestTemplate.d.ts.map +1 -1
- package/build/plugins/resource/appstudio/manifestTemplate.js +6 -0
- package/build/plugins/resource/appstudio/manifestTemplate.js.map +1 -1
- package/build/plugins/resource/appstudio/plugin.d.ts +2 -2
- package/build/plugins/resource/appstudio/plugin.d.ts.map +1 -1
- package/build/plugins/resource/appstudio/plugin.js +70 -16
- package/build/plugins/resource/appstudio/plugin.js.map +1 -1
- package/build/plugins/resource/appstudio/v3/index.d.ts +5 -1
- package/build/plugins/resource/appstudio/v3/index.d.ts.map +1 -1
- package/build/plugins/resource/appstudio/v3/index.js +24 -2
- package/build/plugins/resource/appstudio/v3/index.js.map +1 -1
- package/build/plugins/resource/bot/azureOps.d.ts +1 -1
- package/build/plugins/resource/bot/azureOps.d.ts.map +1 -1
- package/build/plugins/resource/bot/azureOps.js +12 -28
- package/build/plugins/resource/bot/azureOps.js.map +1 -1
- package/build/plugins/resource/bot/clientFactory.d.ts +0 -5
- package/build/plugins/resource/bot/clientFactory.d.ts.map +1 -1
- package/build/plugins/resource/bot/clientFactory.js +1 -29
- package/build/plugins/resource/bot/clientFactory.js.map +1 -1
- package/build/plugins/resource/bot/configs/scaffoldConfig.d.ts +8 -4
- package/build/plugins/resource/bot/configs/scaffoldConfig.d.ts.map +1 -1
- package/build/plugins/resource/bot/configs/scaffoldConfig.js +40 -8
- package/build/plugins/resource/bot/configs/scaffoldConfig.js.map +1 -1
- package/build/plugins/resource/bot/configs/teamsBotConfig.d.ts +1 -1
- package/build/plugins/resource/bot/configs/teamsBotConfig.d.ts.map +1 -1
- package/build/plugins/resource/bot/configs/teamsBotConfig.js +15 -9
- package/build/plugins/resource/bot/configs/teamsBotConfig.js.map +1 -1
- package/build/plugins/resource/bot/constants.d.ts +6 -12
- package/build/plugins/resource/bot/constants.d.ts.map +1 -1
- package/build/plugins/resource/bot/constants.js +5 -11
- package/build/plugins/resource/bot/constants.js.map +1 -1
- package/build/plugins/resource/bot/enums/pluginActRoles.d.ts +2 -1
- package/build/plugins/resource/bot/enums/pluginActRoles.d.ts.map +1 -1
- package/build/plugins/resource/bot/enums/pluginActRoles.js +1 -0
- package/build/plugins/resource/bot/enums/pluginActRoles.js.map +1 -1
- package/build/plugins/resource/bot/errors.d.ts +3 -18
- package/build/plugins/resource/bot/errors.d.ts.map +1 -1
- package/build/plugins/resource/bot/errors.js +8 -38
- package/build/plugins/resource/bot/errors.js.map +1 -1
- package/build/plugins/resource/bot/functionsHostedBot/constants.d.ts +13 -0
- package/build/plugins/resource/bot/functionsHostedBot/constants.d.ts.map +1 -0
- package/build/plugins/resource/bot/functionsHostedBot/constants.js +20 -0
- package/build/plugins/resource/bot/functionsHostedBot/constants.js.map +1 -0
- package/build/plugins/resource/bot/functionsHostedBot/deployMgr.d.ts +18 -0
- package/build/plugins/resource/bot/functionsHostedBot/deployMgr.d.ts.map +1 -0
- package/build/plugins/resource/bot/functionsHostedBot/deployMgr.js +160 -0
- package/build/plugins/resource/bot/functionsHostedBot/deployMgr.js.map +1 -0
- package/build/plugins/resource/bot/functionsHostedBot/plugin.d.ts +2 -0
- package/build/plugins/resource/bot/functionsHostedBot/plugin.d.ts.map +1 -1
- package/build/plugins/resource/bot/functionsHostedBot/plugin.js +104 -2
- package/build/plugins/resource/bot/functionsHostedBot/plugin.js.map +1 -1
- package/build/plugins/resource/bot/index.d.ts +5 -2
- package/build/plugins/resource/bot/index.d.ts.map +1 -1
- package/build/plugins/resource/bot/index.js +10 -5
- package/build/plugins/resource/bot/index.js.map +1 -1
- package/build/plugins/resource/bot/languageStrategy.d.ts.map +1 -1
- package/build/plugins/resource/bot/languageStrategy.js +4 -2
- package/build/plugins/resource/bot/languageStrategy.js.map +1 -1
- package/build/plugins/resource/bot/plugin.d.ts +2 -1
- package/build/plugins/resource/bot/plugin.d.ts.map +1 -1
- package/build/plugins/resource/bot/plugin.js +1 -1
- package/build/plugins/resource/bot/plugin.js.map +1 -1
- package/build/plugins/resource/bot/question.d.ts +4 -1
- package/build/plugins/resource/bot/question.d.ts.map +1 -1
- package/build/plugins/resource/bot/question.js +24 -7
- package/build/plugins/resource/bot/question.js.map +1 -1
- package/build/plugins/resource/bot/resources/messages.d.ts +1 -0
- package/build/plugins/resource/bot/resources/messages.d.ts.map +1 -1
- package/build/plugins/resource/bot/resources/messages.js +5 -1
- package/build/plugins/resource/bot/resources/messages.js.map +1 -1
- package/build/plugins/resource/bot/resources/strings.d.ts +10 -0
- package/build/plugins/resource/bot/resources/strings.d.ts.map +1 -1
- package/build/plugins/resource/bot/resources/strings.js +18 -1
- package/build/plugins/resource/bot/resources/strings.js.map +1 -1
- package/build/plugins/resource/bot/utils/telemetry-helper.d.ts.map +1 -1
- package/build/plugins/resource/bot/utils/telemetry-helper.js +4 -1
- package/build/plugins/resource/bot/utils/telemetry-helper.js.map +1 -1
- package/build/plugins/resource/bot/v3/index.d.ts.map +1 -1
- package/build/plugins/resource/bot/v3/index.js +0 -1
- package/build/plugins/resource/bot/v3/index.js.map +1 -1
- package/build/plugins/resource/cicd/constants.d.ts +3 -3
- package/build/plugins/resource/cicd/constants.d.ts.map +1 -1
- package/build/plugins/resource/cicd/constants.js +4 -3
- package/build/plugins/resource/cicd/constants.js.map +1 -1
- package/build/plugins/resource/cicd/errors.d.ts.map +1 -1
- package/build/plugins/resource/cicd/errors.js.map +1 -1
- package/build/plugins/resource/cicd/index.d.ts.map +1 -1
- package/build/plugins/resource/cicd/index.js +10 -3
- package/build/plugins/resource/cicd/index.js.map +1 -1
- package/build/plugins/resource/cicd/plugin.d.ts.map +1 -1
- package/build/plugins/resource/cicd/plugin.js +14 -12
- package/build/plugins/resource/cicd/plugin.js.map +1 -1
- package/build/plugins/resource/cicd/questions.d.ts +2 -0
- package/build/plugins/resource/cicd/questions.d.ts.map +1 -1
- package/build/plugins/resource/cicd/questions.js +28 -6
- package/build/plugins/resource/cicd/questions.js.map +1 -1
- package/build/plugins/resource/frontend/constants.d.ts +0 -1
- package/build/plugins/resource/frontend/constants.d.ts.map +1 -1
- package/build/plugins/resource/frontend/constants.js +0 -1
- package/build/plugins/resource/frontend/constants.js.map +1 -1
- package/build/plugins/resource/frontend/dotnet/constants.d.ts +0 -1
- package/build/plugins/resource/frontend/dotnet/constants.d.ts.map +1 -1
- package/build/plugins/resource/frontend/dotnet/constants.js +0 -1
- package/build/plugins/resource/frontend/dotnet/constants.js.map +1 -1
- package/build/plugins/resource/frontend/dotnet/ops/scaffold.d.ts.map +1 -1
- package/build/plugins/resource/frontend/dotnet/ops/scaffold.js +0 -1
- package/build/plugins/resource/frontend/dotnet/ops/scaffold.js.map +1 -1
- package/build/plugins/resource/frontend/ops/scaffold.d.ts.map +1 -1
- package/build/plugins/resource/frontend/ops/scaffold.js +0 -1
- package/build/plugins/resource/frontend/ops/scaffold.js.map +1 -1
- package/build/plugins/resource/frontend/resources/templateInfo.d.ts +1 -0
- package/build/plugins/resource/frontend/resources/templateInfo.d.ts.map +1 -1
- package/build/plugins/resource/frontend/resources/templateInfo.js +9 -2
- package/build/plugins/resource/frontend/resources/templateInfo.js.map +1 -1
- package/build/plugins/resource/frontend/v3/index.d.ts.map +1 -1
- package/build/plugins/resource/frontend/v3/index.js +0 -1
- package/build/plugins/resource/frontend/v3/index.js.map +1 -1
- package/build/plugins/resource/function/constants.d.ts +0 -1
- package/build/plugins/resource/function/constants.d.ts.map +1 -1
- package/build/plugins/resource/function/constants.js +0 -1
- package/build/plugins/resource/function/constants.js.map +1 -1
- package/build/plugins/resource/function/ops/scaffold.d.ts.map +1 -1
- package/build/plugins/resource/function/ops/scaffold.js +0 -1
- package/build/plugins/resource/function/ops/scaffold.js.map +1 -1
- package/build/plugins/resource/index.d.ts +1 -0
- package/build/plugins/resource/index.d.ts.map +1 -1
- package/build/plugins/resource/index.js +1 -0
- package/build/plugins/resource/index.js.map +1 -1
- package/build/plugins/resource/localdebug/v2/index.d.ts.map +1 -1
- package/build/plugins/resource/localdebug/v2/index.js +1 -1
- package/build/plugins/resource/localdebug/v2/index.js.map +1 -1
- package/build/plugins/resource/simpleauth/plugin.d.ts.map +1 -1
- package/build/plugins/resource/simpleauth/plugin.js +24 -5
- package/build/plugins/resource/simpleauth/plugin.js.map +1 -1
- package/build/plugins/resource/simpleauth/v2/index.d.ts +2 -2
- package/build/plugins/resource/simpleauth/v2/index.d.ts.map +1 -1
- package/build/plugins/resource/simpleauth/v2/index.js +4 -4
- package/build/plugins/resource/simpleauth/v2/index.js.map +1 -1
- package/build/plugins/resource/spfx/depsChecker/dependencyChecker.d.ts +11 -0
- package/build/plugins/resource/spfx/depsChecker/dependencyChecker.d.ts.map +1 -0
- package/build/plugins/resource/spfx/depsChecker/dependencyChecker.js +5 -0
- package/build/plugins/resource/spfx/depsChecker/dependencyChecker.js.map +1 -0
- package/build/plugins/resource/spfx/depsChecker/generatorChecker.d.ts +21 -0
- package/build/plugins/resource/spfx/depsChecker/generatorChecker.d.ts.map +1 -0
- package/build/plugins/resource/spfx/depsChecker/generatorChecker.js +131 -0
- package/build/plugins/resource/spfx/depsChecker/generatorChecker.js.map +1 -0
- package/build/plugins/resource/spfx/depsChecker/yoChecker.d.ts +21 -0
- package/build/plugins/resource/spfx/depsChecker/yoChecker.d.ts.map +1 -0
- package/build/plugins/resource/spfx/depsChecker/yoChecker.js +128 -0
- package/build/plugins/resource/spfx/depsChecker/yoChecker.js.map +1 -0
- package/build/plugins/resource/spfx/error.d.ts +4 -0
- package/build/plugins/resource/spfx/error.d.ts.map +1 -1
- package/build/plugins/resource/spfx/error.js +17 -1
- package/build/plugins/resource/spfx/error.js.map +1 -1
- package/build/plugins/resource/spfx/index.d.ts.map +1 -1
- package/build/plugins/resource/spfx/index.js +5 -2
- package/build/plugins/resource/spfx/index.js.map +1 -1
- package/build/plugins/resource/spfx/plugin.d.ts.map +1 -1
- package/build/plugins/resource/spfx/plugin.js +62 -13
- package/build/plugins/resource/spfx/plugin.js.map +1 -1
- package/build/plugins/resource/spfx/utils/constants.d.ts +5 -2
- package/build/plugins/resource/spfx/utils/constants.d.ts.map +1 -1
- package/build/plugins/resource/spfx/utils/constants.js +5 -2
- package/build/plugins/resource/spfx/utils/constants.js.map +1 -1
- package/build/plugins/resource/spfx/utils/questions.js +1 -1
- package/build/plugins/resource/spfx/utils/questions.js.map +1 -1
- package/build/plugins/resource/spfx/utils/telemetry-helper.d.ts.map +1 -1
- package/build/plugins/resource/spfx/utils/telemetry-helper.js +1 -0
- package/build/plugins/resource/spfx/utils/telemetry-helper.js.map +1 -1
- package/build/plugins/resource/spfx/utils/telemetryEvents.d.ts +11 -0
- package/build/plugins/resource/spfx/utils/telemetryEvents.d.ts.map +1 -0
- package/build/plugins/resource/spfx/utils/telemetryEvents.js +18 -0
- package/build/plugins/resource/spfx/utils/telemetryEvents.js.map +1 -0
- package/build/plugins/resource/spfx/utils/utils.d.ts +1 -0
- package/build/plugins/resource/spfx/utils/utils.d.ts.map +1 -1
- package/build/plugins/resource/spfx/utils/utils.js +16 -0
- package/build/plugins/resource/spfx/utils/utils.js.map +1 -1
- package/build/plugins/resource/sql/errors.d.ts.map +1 -1
- package/build/plugins/resource/sql/errors.js +29 -29
- package/build/plugins/resource/sql/errors.js.map +1 -1
- package/build/plugins/resource/sql/sqlClient.d.ts.map +1 -1
- package/build/plugins/resource/sql/sqlClient.js +2 -8
- package/build/plugins/resource/sql/sqlClient.js.map +1 -1
- package/build/plugins/solution/fx-solution/ResourcePluginContainer.d.ts +1 -0
- package/build/plugins/solution/fx-solution/ResourcePluginContainer.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/ResourcePluginContainer.js +1 -0
- package/build/plugins/solution/fx-solution/ResourcePluginContainer.js.map +1 -1
- package/build/plugins/solution/fx-solution/constants.d.ts +24 -3
- package/build/plugins/solution/fx-solution/constants.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/constants.js +26 -1
- package/build/plugins/solution/fx-solution/constants.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/constants.d.ts +15 -0
- package/build/plugins/solution/fx-solution/debug/constants.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/constants.js +18 -1
- package/build/plugins/solution/fx-solution/debug/constants.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/provisionLocal.d.ts +2 -3
- package/build/plugins/solution/fx-solution/debug/provisionLocal.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/provisionLocal.js +40 -12
- package/build/plugins/solution/fx-solution/debug/provisionLocal.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/scaffolding.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/scaffolding.js +17 -10
- package/build/plugins/solution/fx-solution/debug/scaffolding.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/launch.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/launch.js +19 -6
- package/build/plugins/solution/fx-solution/debug/util/launch.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/launchNext.d.ts +2 -0
- package/build/plugins/solution/fx-solution/debug/util/launchNext.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/launchNext.js +179 -10
- package/build/plugins/solution/fx-solution/debug/util/launchNext.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/settings.d.ts +1 -1
- package/build/plugins/solution/fx-solution/debug/util/settings.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/settings.js +2 -2
- package/build/plugins/solution/fx-solution/debug/util/settings.js.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/tasksNext.d.ts +1 -0
- package/build/plugins/solution/fx-solution/debug/util/tasksNext.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/debug/util/tasksNext.js +74 -1
- package/build/plugins/solution/fx-solution/debug/util/tasksNext.js.map +1 -1
- package/build/plugins/solution/fx-solution/question.d.ts +6 -2
- package/build/plugins/solution/fx-solution/question.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/question.js +33 -4
- package/build/plugins/solution/fx-solution/question.js.map +1 -1
- package/build/plugins/solution/fx-solution/v2/executeUserTask.d.ts +5 -1
- package/build/plugins/solution/fx-solution/v2/executeUserTask.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/v2/executeUserTask.js +432 -135
- package/build/plugins/solution/fx-solution/v2/executeUserTask.js.map +1 -1
- package/build/plugins/solution/fx-solution/v2/executor.d.ts +1 -1
- package/build/plugins/solution/fx-solution/v2/executor.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/v2/executor.js +33 -13
- package/build/plugins/solution/fx-solution/v2/executor.js.map +1 -1
- package/build/plugins/solution/fx-solution/v2/getQuestions.d.ts +1 -1
- package/build/plugins/solution/fx-solution/v2/getQuestions.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/v2/getQuestions.js +102 -37
- package/build/plugins/solution/fx-solution/v2/getQuestions.js.map +1 -1
- package/build/plugins/solution/fx-solution/v2/provisionLocal.d.ts +1 -2
- package/build/plugins/solution/fx-solution/v2/provisionLocal.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/v2/provisionLocal.js.map +1 -1
- package/build/plugins/solution/fx-solution/v2/scaffolding.d.ts +1 -1
- package/build/plugins/solution/fx-solution/v2/scaffolding.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/v2/scaffolding.js +25 -13
- package/build/plugins/solution/fx-solution/v2/scaffolding.js.map +1 -1
- package/build/plugins/solution/fx-solution/v2/utils.d.ts +1 -2
- package/build/plugins/solution/fx-solution/v2/utils.d.ts.map +1 -1
- package/build/plugins/solution/fx-solution/v2/utils.js +28 -8
- package/build/plugins/solution/fx-solution/v2/utils.js.map +1 -1
- package/build/plugins/solution/fx-solution/v3/provision.js +1 -1
- package/build/plugins/solution/fx-solution/v3/provision.js.map +1 -1
- package/build/plugins/solution/fx-solution/v3/userTask.js +1 -1
- package/build/plugins/solution/fx-solution/v3/userTask.js.map +1 -1
- package/package.json +4 -3
- package/resource/package.nls.json +160 -36
- package/templates/core/README-auto-generated.md +31 -0
- package/templates/{plugins/resource/dotnet → fallback}/blazor-base.csharp.default.zip +0 -0
- package/templates/{plugins/resource/bot → fallback}/bot.csharp.default.zip +0 -0
- package/templates/fallback/bot.js.command-and-response.zip +0 -0
- package/templates/{plugins/resource/bot → fallback}/bot.js.default.zip +0 -0
- package/templates/fallback/bot.js.notification-function-base.zip +0 -0
- package/templates/fallback/bot.js.notification-restify.zip +0 -0
- package/templates/fallback/bot.js.notification-trigger-http.zip +0 -0
- package/templates/fallback/bot.js.notification-trigger-timer.zip +0 -0
- package/templates/fallback/bot.ts.command-and-response.zip +0 -0
- package/templates/{plugins/resource/bot → fallback}/bot.ts.default.zip +0 -0
- package/templates/fallback/bot.ts.notification-function-base.zip +0 -0
- package/templates/fallback/bot.ts.notification-restify.zip +0 -0
- package/templates/fallback/bot.ts.notification-trigger-http.zip +0 -0
- package/templates/fallback/bot.ts.notification-trigger-timer.zip +0 -0
- package/templates/fallback/bot.ts.notification.zip +0 -0
- package/templates/{plugins/resource/function → fallback}/function-base.js.default.zip +0 -0
- package/templates/{plugins/resource/function → fallback}/function-base.ts.default.zip +0 -0
- package/templates/{plugins/resource/function → fallback}/function-triggers.js.HTTPTrigger.zip +0 -0
- package/templates/{plugins/resource/function → fallback}/function-triggers.ts.HTTPTrigger.zip +0 -0
- package/templates/{plugins/resource/frontend → fallback}/tab.csharp.default.zip +0 -0
- package/templates/fallback/tab.js.default.zip +0 -0
- package/templates/{plugins/resource/frontend/tab.js.default.zip → fallback/tab.js.m365.zip} +0 -0
- package/templates/fallback/tab.js.non-sso.zip +0 -0
- package/templates/fallback/tab.ts.default.zip +0 -0
- package/templates/{plugins/resource/frontend/tab.ts.default.zip → fallback/tab.ts.m365.zip} +0 -0
- package/templates/fallback/tab.ts.non-sso.zip +0 -0
- package/templates/plugins/resource/aad/auth/bot/README.md +63 -0
- package/templates/plugins/resource/aad/auth/bot/js/public/auth-end.html +65 -0
- package/templates/plugins/resource/aad/auth/bot/js/public/auth-start.html +177 -0
- package/templates/plugins/resource/aad/auth/bot/js/sso/showUserInfo.js +19 -0
- package/templates/plugins/resource/aad/auth/bot/js/sso/ssoDialog.js +173 -0
- package/templates/plugins/resource/aad/auth/bot/js/sso/teamsSsoBot.js +55 -0
- package/templates/plugins/resource/aad/auth/bot/ts/public/auth-end.html +65 -0
- package/templates/plugins/resource/aad/auth/bot/ts/public/auth-start.html +177 -0
- package/templates/plugins/resource/aad/auth/bot/ts/sso/showUserInfo.ts +24 -0
- package/templates/plugins/resource/aad/auth/bot/ts/sso/ssoDialog.ts +182 -0
- package/templates/plugins/resource/aad/auth/bot/ts/sso/teamsSsoBot.ts +69 -0
- package/templates/plugins/resource/aad/auth/tab/README.md +49 -0
- package/templates/plugins/resource/aad/auth/tab/js/public/auth-end.html +58 -0
- package/templates/plugins/resource/aad/auth/tab/js/public/auth-start.html +57 -0
- package/templates/plugins/resource/aad/auth/tab/js/sso/GetUserProfile.jsx +34 -0
- package/templates/plugins/resource/aad/auth/tab/ts/public/auth-end.html +58 -0
- package/templates/plugins/resource/aad/auth/tab/ts/public/auth-start.html +57 -0
- package/templates/plugins/resource/aad/auth/tab/ts/sso/GetUserProfile.tsx +34 -0
- package/templates/plugins/resource/aad/manifest/aad.template.json +7 -14
- package/templates/plugins/resource/apiconnector/sample/js/api-connector.template +30 -0
- package/templates/plugins/resource/apiconnector/sample/ts/api-connector.template +30 -0
- package/templates/plugins/resource/bot/bicep/botProvision.template.bicep +6 -0
- package/templates/plugins/resource/bot/bicep/funcHostedBotProvision.template.bicep +127 -0
- package/templates/plugins/resource/function/bicep/functionProvision.template.bicep +2 -0
- package/templates/plugins/resource/simpleauth/bicep/simpleAuthProvision.template.bicep +4 -0
- package/templates/plugins/resource/spfx/solution/README.md +2 -2
- package/templates/plugins/resource/sql/bicep/sqlProvision.template.bicep +1 -0
- package/templates/plugins/resource/webapp/bicep/webappProvision.template.bicep +2 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<!--This file is used during the Teams Bot authentication flow to assist with retrieval of the access token.-->
|
|
2
|
+
<!--If you're not familiar with this, do not alter or remove this file from your project.-->
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<title>Login Start Page</title>
|
|
6
|
+
<meta charset="utf-8" />
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
<script type="text/javascript">
|
|
11
|
+
popUpSignInWindow();
|
|
12
|
+
|
|
13
|
+
async function popUpSignInWindow() {
|
|
14
|
+
// Generate random state string and store it, so we can verify it in the callback
|
|
15
|
+
let state = _guid();
|
|
16
|
+
localStorage.setItem("state", state);
|
|
17
|
+
localStorage.removeItem("codeVerifier");
|
|
18
|
+
var currentURL = new URL(window.location);
|
|
19
|
+
var clientId = currentURL.searchParams.get("clientId");
|
|
20
|
+
var tenantId = currentURL.searchParams.get("tenantId");
|
|
21
|
+
var loginHint = currentURL.searchParams.get("loginHint");
|
|
22
|
+
if (!loginHint) {
|
|
23
|
+
loginHint = "";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var scope = currentURL.searchParams.get("scope");
|
|
27
|
+
|
|
28
|
+
var originalCode = _guid();
|
|
29
|
+
var codeChallenge = await pkceChallengeFromVerifier(originalCode);
|
|
30
|
+
|
|
31
|
+
localStorage.setItem("codeVerifier", originalCode);
|
|
32
|
+
let queryParams = {
|
|
33
|
+
client_id: clientId,
|
|
34
|
+
response_type: "code",
|
|
35
|
+
response_mode: "fragment",
|
|
36
|
+
scope: scope,
|
|
37
|
+
redirect_uri: window.location.origin + "/auth-end.html",
|
|
38
|
+
nonce: _guid(),
|
|
39
|
+
login_hint: loginHint,
|
|
40
|
+
state: state,
|
|
41
|
+
code_challenge: codeChallenge,
|
|
42
|
+
code_challenge_method: "S256",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
let authorizeEndpoint = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?${toQueryString(
|
|
46
|
+
queryParams
|
|
47
|
+
)}`;
|
|
48
|
+
window.location.assign(authorizeEndpoint);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Build query string from map of query parameter
|
|
52
|
+
function toQueryString(queryParams) {
|
|
53
|
+
let encodedQueryParams = [];
|
|
54
|
+
for (let key in queryParams) {
|
|
55
|
+
encodedQueryParams.push(key + "=" + encodeURIComponent(queryParams[key]));
|
|
56
|
+
}
|
|
57
|
+
return encodedQueryParams.join("&");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Converts decimal to hex equivalent
|
|
61
|
+
// (From ADAL.js: https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js)
|
|
62
|
+
function _decimalToHex(number) {
|
|
63
|
+
var hex = number.toString(16);
|
|
64
|
+
while (hex.length < 2) {
|
|
65
|
+
hex = "0" + hex;
|
|
66
|
+
}
|
|
67
|
+
return hex;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Generates RFC4122 version 4 guid (128 bits)
|
|
71
|
+
// (From ADAL.js: https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js)
|
|
72
|
+
function _guid() {
|
|
73
|
+
// RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or
|
|
74
|
+
// pseudo-random numbers.
|
|
75
|
+
// The algorithm is as follows:
|
|
76
|
+
// Set the two most significant bits (bits 6 and 7) of the
|
|
77
|
+
// clock_seq_hi_and_reserved to zero and one, respectively.
|
|
78
|
+
// Set the four most significant bits (bits 12 through 15) of the
|
|
79
|
+
// time_hi_and_version field to the 4-bit version number from
|
|
80
|
+
// Section 4.1.3. Version4
|
|
81
|
+
// Set all the other bits to randomly (or pseudo-randomly) chosen
|
|
82
|
+
// values.
|
|
83
|
+
// UUID = time-low "-" time-mid "-"time-high-and-version "-"clock-seq-reserved and low(2hexOctet)"-" node
|
|
84
|
+
// time-low = 4hexOctet
|
|
85
|
+
// time-mid = 2hexOctet
|
|
86
|
+
// time-high-and-version = 2hexOctet
|
|
87
|
+
// clock-seq-and-reserved = hexOctet:
|
|
88
|
+
// clock-seq-low = hexOctet
|
|
89
|
+
// node = 6hexOctet
|
|
90
|
+
// Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
91
|
+
// y could be 1000, 1001, 1010, 1011 since most significant two bits needs to be 10
|
|
92
|
+
// y values are 8, 9, A, B
|
|
93
|
+
var cryptoObj = window.crypto || window.msCrypto; // for IE 11
|
|
94
|
+
if (cryptoObj && cryptoObj.getRandomValues) {
|
|
95
|
+
var buffer = new Uint8Array(16);
|
|
96
|
+
cryptoObj.getRandomValues(buffer);
|
|
97
|
+
//buffer[6] and buffer[7] represents the time_hi_and_version field. We will set the four most significant bits (4 through 7) of buffer[6] to represent decimal number 4 (UUID version number).
|
|
98
|
+
buffer[6] |= 0x40; //buffer[6] | 01000000 will set the 6 bit to 1.
|
|
99
|
+
buffer[6] &= 0x4f; //buffer[6] & 01001111 will set the 4, 5, and 7 bit to 0 such that bits 4-7 == 0100 = "4".
|
|
100
|
+
//buffer[8] represents the clock_seq_hi_and_reserved field. We will set the two most significant bits (6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively.
|
|
101
|
+
buffer[8] |= 0x80; //buffer[8] | 10000000 will set the 7 bit to 1.
|
|
102
|
+
buffer[8] &= 0xbf; //buffer[8] & 10111111 will set the 6 bit to 0.
|
|
103
|
+
return (
|
|
104
|
+
_decimalToHex(buffer[0]) +
|
|
105
|
+
_decimalToHex(buffer[1]) +
|
|
106
|
+
_decimalToHex(buffer[2]) +
|
|
107
|
+
_decimalToHex(buffer[3]) +
|
|
108
|
+
"-" +
|
|
109
|
+
_decimalToHex(buffer[4]) +
|
|
110
|
+
_decimalToHex(buffer[5]) +
|
|
111
|
+
"-" +
|
|
112
|
+
_decimalToHex(buffer[6]) +
|
|
113
|
+
_decimalToHex(buffer[7]) +
|
|
114
|
+
"-" +
|
|
115
|
+
_decimalToHex(buffer[8]) +
|
|
116
|
+
_decimalToHex(buffer[9]) +
|
|
117
|
+
"-" +
|
|
118
|
+
_decimalToHex(buffer[10]) +
|
|
119
|
+
_decimalToHex(buffer[11]) +
|
|
120
|
+
_decimalToHex(buffer[12]) +
|
|
121
|
+
_decimalToHex(buffer[13]) +
|
|
122
|
+
_decimalToHex(buffer[14]) +
|
|
123
|
+
_decimalToHex(buffer[15])
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
126
|
+
var guidHolder = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
|
|
127
|
+
var hex = "0123456789abcdef";
|
|
128
|
+
var r = 0;
|
|
129
|
+
var guidResponse = "";
|
|
130
|
+
for (var i = 0; i < 36; i++) {
|
|
131
|
+
if (guidHolder[i] !== "-" && guidHolder[i] !== "4") {
|
|
132
|
+
// each x and y needs to be random
|
|
133
|
+
r = (Math.random() * 16) | 0;
|
|
134
|
+
}
|
|
135
|
+
if (guidHolder[i] === "x") {
|
|
136
|
+
guidResponse += hex[r];
|
|
137
|
+
} else if (guidHolder[i] === "y") {
|
|
138
|
+
// clock-seq-and-reserved first hex is filtered and remaining hex values are random
|
|
139
|
+
r &= 0x3; // bit and with 0011 to set pos 2 to zero ?0??
|
|
140
|
+
r |= 0x8; // set pos 3 to 1 as 1???
|
|
141
|
+
guidResponse += hex[r];
|
|
142
|
+
} else {
|
|
143
|
+
guidResponse += guidHolder[i];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return guidResponse;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Calculate the SHA256 hash of the input text.
|
|
151
|
+
// Returns a promise that resolves to an ArrayBuffer
|
|
152
|
+
function sha256(plain) {
|
|
153
|
+
const encoder = new TextEncoder();
|
|
154
|
+
const data = encoder.encode(plain);
|
|
155
|
+
return window.crypto.subtle.digest("SHA-256", data);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Base64-urlencodes the input string
|
|
159
|
+
function base64urlencode(str) {
|
|
160
|
+
// Convert the ArrayBuffer to string using Uint8 array to convert to what btoa accepts.
|
|
161
|
+
// btoa accepts chars only within ascii 0-255 and base64 encodes them.
|
|
162
|
+
// Then convert the base64 encoded to base64url encoded
|
|
163
|
+
// (replace + with -, replace / with _, trim trailing =)
|
|
164
|
+
return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))
|
|
165
|
+
.replace(/\+/g, "-")
|
|
166
|
+
.replace(/\//g, "_")
|
|
167
|
+
.replace(/=+$/, "");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Return the base64-urlencoded sha256 hash for the PKCE challenge
|
|
171
|
+
async function pkceChallengeFromVerifier(v) {
|
|
172
|
+
hashed = await sha256(v);
|
|
173
|
+
return base64urlencode(hashed);
|
|
174
|
+
}
|
|
175
|
+
</script>
|
|
176
|
+
</body>
|
|
177
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createMicrosoftGraphClient, TeamsFx } from "@microsoft/teamsfx";
|
|
2
|
+
|
|
3
|
+
export async function showUserInfo(context, ssoToken) {
|
|
4
|
+
await context.sendActivity("Retrieving user information from Microsoft Graph ...");
|
|
5
|
+
const teamsfx = new TeamsFx().setSsoToken(ssoToken);
|
|
6
|
+
const graphClient = createMicrosoftGraphClient(teamsfx, ["User.Read"]);
|
|
7
|
+
const me = await graphClient.api("/me").get();
|
|
8
|
+
if (me) {
|
|
9
|
+
await context.sendActivity(
|
|
10
|
+
`You're logged in as ${me.displayName} (${me.userPrincipalName})${
|
|
11
|
+
me.jobTitle ? `; your job title is: ${me.jobTitle}` : ""
|
|
12
|
+
}.`
|
|
13
|
+
);
|
|
14
|
+
} else {
|
|
15
|
+
await context.sendActivity("Could not retrieve profile information from Microsoft Graph.");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ComponentDialog,
|
|
3
|
+
WaterfallDialog,
|
|
4
|
+
Dialog,
|
|
5
|
+
DialogTurnResult,
|
|
6
|
+
DialogSet,
|
|
7
|
+
DialogTurnStatus,
|
|
8
|
+
} from "botbuilder-dialogs";
|
|
9
|
+
import { ActivityTypes, tokenExchangeOperationName, TurnContext } from "botbuilder";
|
|
10
|
+
import { TeamsBotSsoPrompt, TeamsFx } from "@microsoft/teamsfx";
|
|
11
|
+
import "isomorphic-fetch";
|
|
12
|
+
|
|
13
|
+
const DIALOG_NAME = "SSODialog";
|
|
14
|
+
const TEAMS_SSO_PROMPT_ID = "TeamsFxSsoPrompt";
|
|
15
|
+
const COMMAND_ROUTE_DIALOG = "CommandRouteDialog";
|
|
16
|
+
|
|
17
|
+
export class SsoDialog extends ComponentDialog {
|
|
18
|
+
constructor(dedupStorage, requiredScopes) {
|
|
19
|
+
super(DIALOG_NAME);
|
|
20
|
+
|
|
21
|
+
this.initialDialogId = COMMAND_ROUTE_DIALOG;
|
|
22
|
+
|
|
23
|
+
this.dedupStorage = dedupStorage;
|
|
24
|
+
this.dedupStorageKeys = [];
|
|
25
|
+
this.requiredScopes = requiredScopes;
|
|
26
|
+
|
|
27
|
+
const teamsFx = new TeamsFx();
|
|
28
|
+
const ssoDialog = new TeamsBotSsoPrompt(teamsFx, TEAMS_SSO_PROMPT_ID, {
|
|
29
|
+
scopes: this.requiredScopes,
|
|
30
|
+
endOnInvalidMessage: true,
|
|
31
|
+
});
|
|
32
|
+
this.addDialog(ssoDialog);
|
|
33
|
+
|
|
34
|
+
const commandRouteDialog = new WaterfallDialog(COMMAND_ROUTE_DIALOG, [
|
|
35
|
+
this.commandRouteStep.bind(this),
|
|
36
|
+
]);
|
|
37
|
+
this.addDialog(commandRouteDialog);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
addCommand(commandId, commandText, operation) {
|
|
41
|
+
const dialog = new WaterfallDialog(commandId, [
|
|
42
|
+
this.ssoStep.bind(this),
|
|
43
|
+
this.dedupStep.bind(this),
|
|
44
|
+
async (stepContext) => {
|
|
45
|
+
const tokenResponse = stepContext.result;
|
|
46
|
+
const context = stepContext.context;
|
|
47
|
+
if (tokenResponse) {
|
|
48
|
+
await operation(context, tokenResponse.ssoToken);
|
|
49
|
+
} else {
|
|
50
|
+
await context.sendActivity("Failed to retrieve user token from conversation context.");
|
|
51
|
+
}
|
|
52
|
+
return await stepContext.endDialog();
|
|
53
|
+
},
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
if (this.commandMapping.has(commandId)) {
|
|
57
|
+
throw new Error(`Cannot add command. There is already a command with same id ${commandId}`);
|
|
58
|
+
}
|
|
59
|
+
this.commandMapping.set(commandId, commandText);
|
|
60
|
+
this.addDialog(dialog);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The run method handles the incoming activity (in the form of a DialogContext) and passes it through the dialog system.
|
|
65
|
+
* If no dialog is active, it will start the default dialog.
|
|
66
|
+
* @param {*} dialogContext
|
|
67
|
+
*/
|
|
68
|
+
async run(context, accessor) {
|
|
69
|
+
const dialogSet = new DialogSet(accessor);
|
|
70
|
+
dialogSet.add(this);
|
|
71
|
+
|
|
72
|
+
const dialogContext = await dialogSet.createContext(context);
|
|
73
|
+
const results = await dialogContext.continueDialog();
|
|
74
|
+
if (results && results.status === DialogTurnStatus.empty) {
|
|
75
|
+
await dialogContext.beginDialog(this.id);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async commandRouteStep(stepContext) {
|
|
80
|
+
const turnContext = stepContext.context;
|
|
81
|
+
|
|
82
|
+
// remove the mention of this bot
|
|
83
|
+
let text = TurnContext.removeRecipientMention(turnContext.activity);
|
|
84
|
+
if (text) {
|
|
85
|
+
// remove the line break
|
|
86
|
+
text = text.toLowerCase().replace(/\n|\r/g, "").trim();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const commandId = this.matchCommands(text);
|
|
90
|
+
if (commandId) {
|
|
91
|
+
return await stepContext.beginDialog(commandId);
|
|
92
|
+
}
|
|
93
|
+
return await stepContext.endDialog();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async ssoStep(stepContext) {
|
|
97
|
+
return await stepContext.beginDialog(TEAMS_SSO_PROMPT_ID);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async dedupStep(stepContext) {
|
|
101
|
+
const tokenResponse = stepContext.result;
|
|
102
|
+
// Only dedup after ssoStep to make sure that all Teams client would receive the login request
|
|
103
|
+
if (tokenResponse && (await this.shouldDedup(stepContext.context))) {
|
|
104
|
+
return Dialog.EndOfTurn;
|
|
105
|
+
}
|
|
106
|
+
return await stepContext.next(tokenResponse);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async onEndDialog(context) {
|
|
110
|
+
const conversationId = context.activity.conversation.id;
|
|
111
|
+
const currentDedupKeys = this.dedupStorageKeys.filter((key) => key.indexOf(conversationId) > 0);
|
|
112
|
+
await this.dedupStorage.delete(currentDedupKeys);
|
|
113
|
+
this.dedupStorageKeys = this.dedupStorageKeys.filter((key) => key.indexOf(conversationId) < 0);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// If a user is signed into multiple Teams clients, the Bot might receive a "signin/tokenExchange" from each client.
|
|
117
|
+
// Each token exchange request for a specific user login will have an identical activity.value.Id.
|
|
118
|
+
// Only one of these token exchange requests should be processed by the bot. For a distributed bot in production,
|
|
119
|
+
// this requires a distributed storage to ensure only one token exchange is processed.
|
|
120
|
+
async shouldDedup(context) {
|
|
121
|
+
const storeItem = {
|
|
122
|
+
eTag: context.activity.value.id,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const key = this.getStorageKey(context);
|
|
126
|
+
const storeItems = { [key]: storeItem };
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
await this.dedupStorage.write(storeItems);
|
|
130
|
+
this.dedupStorageKeys.push(key);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
if (err instanceof Error && err.message.indexOf("eTag conflict")) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
getStorageKey(context) {
|
|
141
|
+
if (!context || !context.activity || !context.activity.conversation) {
|
|
142
|
+
throw new Error("Invalid context, can not get storage key!");
|
|
143
|
+
}
|
|
144
|
+
const activity = context.activity;
|
|
145
|
+
const channelId = activity.channelId;
|
|
146
|
+
const conversationId = activity.conversation.id;
|
|
147
|
+
if (activity.type !== ActivityTypes.Invoke || activity.name !== tokenExchangeOperationName) {
|
|
148
|
+
throw new Error("TokenExchangeState can only be used with Invokes of signin/tokenExchange.");
|
|
149
|
+
}
|
|
150
|
+
const value = activity.value;
|
|
151
|
+
if (!value || !value.id) {
|
|
152
|
+
throw new Error("Invalid signin/tokenExchange. Missing activity.value.id.");
|
|
153
|
+
}
|
|
154
|
+
return `${channelId}/${conversationId}/${value.id}`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
matchCommands(text) {
|
|
158
|
+
for (const command of this.commandMapping) {
|
|
159
|
+
let pattern = command[1];
|
|
160
|
+
let matchResult;
|
|
161
|
+
if (typeof pattern == "string") {
|
|
162
|
+
matchResult = text === pattern;
|
|
163
|
+
} else {
|
|
164
|
+
matchResult = pattern.exec(text);
|
|
165
|
+
}
|
|
166
|
+
if (matchResult) {
|
|
167
|
+
return command[0]; // Return the command id
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ConversationState, MemoryStorage, TeamsActivityHandler, UserState } from "botbuilder";
|
|
2
|
+
import { showUserInfo } from "./showUserInfo";
|
|
3
|
+
import { SsoDialog } from "./ssoDialog";
|
|
4
|
+
|
|
5
|
+
export class TeamsSsoBot extends TeamsActivityHandler {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
|
|
9
|
+
// Define the state store for your bot.
|
|
10
|
+
// See https://aka.ms/about-bot-state to learn more about using MemoryStorage.
|
|
11
|
+
// A bot requires a state storage system to persist the dialog and user state between messages.
|
|
12
|
+
const memoryStorage = new MemoryStorage();
|
|
13
|
+
|
|
14
|
+
// Create conversation and user state with in-memory storage provider.
|
|
15
|
+
this.conversationState = new ConversationState(memoryStorage);
|
|
16
|
+
this.userState = new UserState(memoryStorage);
|
|
17
|
+
this.dialog = new SsoDialog(new MemoryStorage(), ["User.Read"]);
|
|
18
|
+
this.dialogState = this.conversationState.createProperty("DialogState");
|
|
19
|
+
|
|
20
|
+
// Add commands that requires user authentication
|
|
21
|
+
this.dialog.addCommand("ShowUserProfile", "show", showUserInfo);
|
|
22
|
+
// call the `addCommand` function to add more customized commands
|
|
23
|
+
|
|
24
|
+
this.onMessage(async (context, next) => {
|
|
25
|
+
console.log("Running with Message Activity.");
|
|
26
|
+
|
|
27
|
+
// Run the Dialog with the new message Activity.
|
|
28
|
+
await this.dialog.run(context, this.dialogState);
|
|
29
|
+
|
|
30
|
+
// By calling next() you ensure that the next BotHandler is run.
|
|
31
|
+
await next();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async run(context) {
|
|
36
|
+
await super.run(context);
|
|
37
|
+
|
|
38
|
+
// Save any state changes. The load happened during the execution of the Dialog.
|
|
39
|
+
await this.conversationState.saveChanges(context, false);
|
|
40
|
+
await this.userState.saveChanges(context, false);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async handleTeamsSigninVerifyState(context, query) {
|
|
44
|
+
console.log("Running dialog with signin/verifystate from an Invoke Activity.");
|
|
45
|
+
await this.dialog.run(context, this.dialogState);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async handleTeamsSigninTokenExchange(context, query) {
|
|
49
|
+
await this.dialog.run(context, this.dialogState);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async onSignInInvoke(context) {
|
|
53
|
+
await this.dialog.run(context, this.dialogState);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Login End Page</title>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
</head>
|
|
6
|
+
|
|
7
|
+
<body>
|
|
8
|
+
<script
|
|
9
|
+
src="https://statics.teams.cdn.office.net/sdk/v1.6.0/js/MicrosoftTeams.min.js"
|
|
10
|
+
integrity="sha384-mhp2E+BLMiZLe7rDIzj19WjgXJeI32NkPvrvvZBrMi5IvWup/1NUfS5xuYN5S3VT"
|
|
11
|
+
crossorigin="anonymous"
|
|
12
|
+
></script>
|
|
13
|
+
<div id="divError"></div>
|
|
14
|
+
<script type="text/javascript">
|
|
15
|
+
microsoftTeams.initialize();
|
|
16
|
+
let hashParams = getHashParameters();
|
|
17
|
+
|
|
18
|
+
if (hashParams["error"]) {
|
|
19
|
+
// Authentication failed
|
|
20
|
+
handleAuthError(hashParams["error"], hashParams);
|
|
21
|
+
} else if (hashParams["code"]) {
|
|
22
|
+
// Get the stored state parameter and compare with incoming state
|
|
23
|
+
let expectedState = localStorage.getItem("state");
|
|
24
|
+
if (expectedState !== hashParams["state"]) {
|
|
25
|
+
// State does not match, report error
|
|
26
|
+
handleAuthError("StateDoesNotMatch", hashParams);
|
|
27
|
+
} else {
|
|
28
|
+
microsoftTeams.authentication.notifySuccess();
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
// Unexpected condition: hash does not contain error or access_token parameter
|
|
32
|
+
handleAuthError("UnexpectedFailure", hashParams);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Parse hash parameters into key-value pairs
|
|
36
|
+
function getHashParameters() {
|
|
37
|
+
let hashParams = {};
|
|
38
|
+
location.hash
|
|
39
|
+
.substr(1)
|
|
40
|
+
.split("&")
|
|
41
|
+
.forEach(function (item) {
|
|
42
|
+
let s = item.split("="),
|
|
43
|
+
k = s[0],
|
|
44
|
+
v = s[1] && decodeURIComponent(s[1]);
|
|
45
|
+
hashParams[k] = v;
|
|
46
|
+
});
|
|
47
|
+
return hashParams;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Show error information
|
|
51
|
+
function handleAuthError(errorType, errorMessage) {
|
|
52
|
+
const err = JSON.stringify({
|
|
53
|
+
error: errorType,
|
|
54
|
+
message: JSON.stringify(errorMessage),
|
|
55
|
+
});
|
|
56
|
+
let para = document.createElement("p");
|
|
57
|
+
let node = document.createTextNode(err);
|
|
58
|
+
para.appendChild(node);
|
|
59
|
+
|
|
60
|
+
let element = document.getElementById("divError");
|
|
61
|
+
element.appendChild(para);
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
</body>
|
|
65
|
+
</html>
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<!--This file is used during the Teams Bot authentication flow to assist with retrieval of the access token.-->
|
|
2
|
+
<!--If you're not familiar with this, do not alter or remove this file from your project.-->
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<title>Login Start Page</title>
|
|
6
|
+
<meta charset="utf-8" />
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
<script type="text/javascript">
|
|
11
|
+
popUpSignInWindow();
|
|
12
|
+
|
|
13
|
+
async function popUpSignInWindow() {
|
|
14
|
+
// Generate random state string and store it, so we can verify it in the callback
|
|
15
|
+
let state = _guid();
|
|
16
|
+
localStorage.setItem("state", state);
|
|
17
|
+
localStorage.removeItem("codeVerifier");
|
|
18
|
+
var currentURL = new URL(window.location);
|
|
19
|
+
var clientId = currentURL.searchParams.get("clientId");
|
|
20
|
+
var tenantId = currentURL.searchParams.get("tenantId");
|
|
21
|
+
var loginHint = currentURL.searchParams.get("loginHint");
|
|
22
|
+
if (!loginHint) {
|
|
23
|
+
loginHint = "";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var scope = currentURL.searchParams.get("scope");
|
|
27
|
+
|
|
28
|
+
var originalCode = _guid();
|
|
29
|
+
var codeChallenge = await pkceChallengeFromVerifier(originalCode);
|
|
30
|
+
|
|
31
|
+
localStorage.setItem("codeVerifier", originalCode);
|
|
32
|
+
let queryParams = {
|
|
33
|
+
client_id: clientId,
|
|
34
|
+
response_type: "code",
|
|
35
|
+
response_mode: "fragment",
|
|
36
|
+
scope: scope,
|
|
37
|
+
redirect_uri: window.location.origin + "/auth-end.html",
|
|
38
|
+
nonce: _guid(),
|
|
39
|
+
login_hint: loginHint,
|
|
40
|
+
state: state,
|
|
41
|
+
code_challenge: codeChallenge,
|
|
42
|
+
code_challenge_method: "S256",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
let authorizeEndpoint = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?${toQueryString(
|
|
46
|
+
queryParams
|
|
47
|
+
)}`;
|
|
48
|
+
window.location.assign(authorizeEndpoint);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Build query string from map of query parameter
|
|
52
|
+
function toQueryString(queryParams) {
|
|
53
|
+
let encodedQueryParams = [];
|
|
54
|
+
for (let key in queryParams) {
|
|
55
|
+
encodedQueryParams.push(key + "=" + encodeURIComponent(queryParams[key]));
|
|
56
|
+
}
|
|
57
|
+
return encodedQueryParams.join("&");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Converts decimal to hex equivalent
|
|
61
|
+
// (From ADAL.js: https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js)
|
|
62
|
+
function _decimalToHex(number) {
|
|
63
|
+
var hex = number.toString(16);
|
|
64
|
+
while (hex.length < 2) {
|
|
65
|
+
hex = "0" + hex;
|
|
66
|
+
}
|
|
67
|
+
return hex;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Generates RFC4122 version 4 guid (128 bits)
|
|
71
|
+
// (From ADAL.js: https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js)
|
|
72
|
+
function _guid() {
|
|
73
|
+
// RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or
|
|
74
|
+
// pseudo-random numbers.
|
|
75
|
+
// The algorithm is as follows:
|
|
76
|
+
// Set the two most significant bits (bits 6 and 7) of the
|
|
77
|
+
// clock_seq_hi_and_reserved to zero and one, respectively.
|
|
78
|
+
// Set the four most significant bits (bits 12 through 15) of the
|
|
79
|
+
// time_hi_and_version field to the 4-bit version number from
|
|
80
|
+
// Section 4.1.3. Version4
|
|
81
|
+
// Set all the other bits to randomly (or pseudo-randomly) chosen
|
|
82
|
+
// values.
|
|
83
|
+
// UUID = time-low "-" time-mid "-"time-high-and-version "-"clock-seq-reserved and low(2hexOctet)"-" node
|
|
84
|
+
// time-low = 4hexOctet
|
|
85
|
+
// time-mid = 2hexOctet
|
|
86
|
+
// time-high-and-version = 2hexOctet
|
|
87
|
+
// clock-seq-and-reserved = hexOctet:
|
|
88
|
+
// clock-seq-low = hexOctet
|
|
89
|
+
// node = 6hexOctet
|
|
90
|
+
// Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
91
|
+
// y could be 1000, 1001, 1010, 1011 since most significant two bits needs to be 10
|
|
92
|
+
// y values are 8, 9, A, B
|
|
93
|
+
var cryptoObj = window.crypto || window.msCrypto; // for IE 11
|
|
94
|
+
if (cryptoObj && cryptoObj.getRandomValues) {
|
|
95
|
+
var buffer = new Uint8Array(16);
|
|
96
|
+
cryptoObj.getRandomValues(buffer);
|
|
97
|
+
//buffer[6] and buffer[7] represents the time_hi_and_version field. We will set the four most significant bits (4 through 7) of buffer[6] to represent decimal number 4 (UUID version number).
|
|
98
|
+
buffer[6] |= 0x40; //buffer[6] | 01000000 will set the 6 bit to 1.
|
|
99
|
+
buffer[6] &= 0x4f; //buffer[6] & 01001111 will set the 4, 5, and 7 bit to 0 such that bits 4-7 == 0100 = "4".
|
|
100
|
+
//buffer[8] represents the clock_seq_hi_and_reserved field. We will set the two most significant bits (6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively.
|
|
101
|
+
buffer[8] |= 0x80; //buffer[8] | 10000000 will set the 7 bit to 1.
|
|
102
|
+
buffer[8] &= 0xbf; //buffer[8] & 10111111 will set the 6 bit to 0.
|
|
103
|
+
return (
|
|
104
|
+
_decimalToHex(buffer[0]) +
|
|
105
|
+
_decimalToHex(buffer[1]) +
|
|
106
|
+
_decimalToHex(buffer[2]) +
|
|
107
|
+
_decimalToHex(buffer[3]) +
|
|
108
|
+
"-" +
|
|
109
|
+
_decimalToHex(buffer[4]) +
|
|
110
|
+
_decimalToHex(buffer[5]) +
|
|
111
|
+
"-" +
|
|
112
|
+
_decimalToHex(buffer[6]) +
|
|
113
|
+
_decimalToHex(buffer[7]) +
|
|
114
|
+
"-" +
|
|
115
|
+
_decimalToHex(buffer[8]) +
|
|
116
|
+
_decimalToHex(buffer[9]) +
|
|
117
|
+
"-" +
|
|
118
|
+
_decimalToHex(buffer[10]) +
|
|
119
|
+
_decimalToHex(buffer[11]) +
|
|
120
|
+
_decimalToHex(buffer[12]) +
|
|
121
|
+
_decimalToHex(buffer[13]) +
|
|
122
|
+
_decimalToHex(buffer[14]) +
|
|
123
|
+
_decimalToHex(buffer[15])
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
126
|
+
var guidHolder = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
|
|
127
|
+
var hex = "0123456789abcdef";
|
|
128
|
+
var r = 0;
|
|
129
|
+
var guidResponse = "";
|
|
130
|
+
for (var i = 0; i < 36; i++) {
|
|
131
|
+
if (guidHolder[i] !== "-" && guidHolder[i] !== "4") {
|
|
132
|
+
// each x and y needs to be random
|
|
133
|
+
r = (Math.random() * 16) | 0;
|
|
134
|
+
}
|
|
135
|
+
if (guidHolder[i] === "x") {
|
|
136
|
+
guidResponse += hex[r];
|
|
137
|
+
} else if (guidHolder[i] === "y") {
|
|
138
|
+
// clock-seq-and-reserved first hex is filtered and remaining hex values are random
|
|
139
|
+
r &= 0x3; // bit and with 0011 to set pos 2 to zero ?0??
|
|
140
|
+
r |= 0x8; // set pos 3 to 1 as 1???
|
|
141
|
+
guidResponse += hex[r];
|
|
142
|
+
} else {
|
|
143
|
+
guidResponse += guidHolder[i];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return guidResponse;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Calculate the SHA256 hash of the input text.
|
|
151
|
+
// Returns a promise that resolves to an ArrayBuffer
|
|
152
|
+
function sha256(plain) {
|
|
153
|
+
const encoder = new TextEncoder();
|
|
154
|
+
const data = encoder.encode(plain);
|
|
155
|
+
return window.crypto.subtle.digest("SHA-256", data);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Base64-urlencodes the input string
|
|
159
|
+
function base64urlencode(str) {
|
|
160
|
+
// Convert the ArrayBuffer to string using Uint8 array to convert to what btoa accepts.
|
|
161
|
+
// btoa accepts chars only within ascii 0-255 and base64 encodes them.
|
|
162
|
+
// Then convert the base64 encoded to base64url encoded
|
|
163
|
+
// (replace + with -, replace / with _, trim trailing =)
|
|
164
|
+
return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))
|
|
165
|
+
.replace(/\+/g, "-")
|
|
166
|
+
.replace(/\//g, "_")
|
|
167
|
+
.replace(/=+$/, "");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Return the base64-urlencoded sha256 hash for the PKCE challenge
|
|
171
|
+
async function pkceChallengeFromVerifier(v) {
|
|
172
|
+
hashed = await sha256(v);
|
|
173
|
+
return base64urlencode(hashed);
|
|
174
|
+
}
|
|
175
|
+
</script>
|
|
176
|
+
</body>
|
|
177
|
+
</html>
|