diff --git a/example.php b/example.php index bc13d64bc..9e7939cea 100644 --- a/example.php +++ b/example.php @@ -41,7 +41,7 @@ function getSSLPage($url) { $platform = 'console'; // $platform = 'server'; - $spec = getSSLPage("https://raw.githubusercontent.com/appwrite/appwrite/feat-rc-sdks/app/config/specs/swagger2-latest-{$platform}.json"); + $spec = getSSLPage("https://raw.githubusercontent.com/appwrite/appwrite/1.5.x/app/config/specs/swagger2-latest-{$platform}.json"); if(empty($spec)) { throw new Exception('Failed to fetch spec from Appwrite server'); diff --git a/templates/cli/lib/commands/generic.js.twig b/templates/cli/lib/commands/generic.js.twig index c3fe7da4b..f66a36ea3 100644 --- a/templates/cli/lib/commands/generic.js.twig +++ b/templates/cli/lib/commands/generic.js.twig @@ -5,8 +5,8 @@ const { sdkForConsole } = require("../sdks"); const { globalConfig, localConfig } = require("../config"); const { actionRunner, success, parseBool, commandDescriptions, log, parse } = require("../parser"); {% if sdk.test != "true" %} -const { questionsLogin } = require("../questions"); -const { accountCreateEmailPasswordSession, accountDeleteSession } = require("./account"); +const { questionsLogin, questionsListFactors, questionsMfaChallenge } = require("../questions"); +const { accountUpdateMfaChallenge, accountCreateMfaChallenge, accountGet, accountCreateEmailPasswordSession, accountDeleteSession } = require("./account"); const login = new Command("login") .description(commandDescriptions['login']) @@ -25,7 +25,44 @@ const login = new Command("login") sdk: client }) - success() + client.setCookie(globalConfig.getCookie()); + + let account; + + try { + account = await accountGet({ + sdk: client, + parseOutput: false + }); + } catch(error) { + if (error.response === 'user_more_factors_required') { + const { factor } = await inquirer.prompt(questionsListFactors); + + const challenge = await accountCreateMfaChallenge({ + factor, + parseOutput: false, + sdk: client + }); + + const { otp } = await inquirer.prompt(questionsMfaChallenge); + + await accountUpdateMfaChallenge({ + challengeId: challenge.$id, + otp, + parseOutput: false, + sdk: client + }); + + account = await accountGet({ + sdk: client, + parseOutput: false + }); + } else { + throw error; + } + } + + success("Signed in as user with ID: " + account.$id); })); const logout = new Command("logout") diff --git a/templates/cli/lib/questions.js.twig b/templates/cli/lib/questions.js.twig index 0cb4540f3..dd79745ed 100644 --- a/templates/cli/lib/questions.js.twig +++ b/templates/cli/lib/questions.js.twig @@ -1,6 +1,9 @@ const { localConfig } = require('./config'); const { projectsList } = require('./commands/projects'); const { functionsListRuntimes } = require('./commands/functions'); +const { accountListMfaFactors } = require("./commands/account"); +const { sdkForConsole } = require("./sdks"); + const { databasesList } = require('./commands/databases'); const JSONbig = require("json-bigint")({ storeAsString: false }); @@ -387,7 +390,57 @@ const questionsDeployTeams = [ name: "override", message: 'Are you sure you want to override this team? This can lead to loss of data! Type "YES" to confirm.' }, -] +]; + +const questionsListFactors = [ + { + type: "list", + name: "factor", + message: "Your account is protected by multiple factors. Which factor would you like to use to authenticate?", + choices: async () => { + let client = await sdkForConsole(false); + const factors = await accountListMfaFactors({ + sdk: client, + parseOutput: false + }); + + const choices = [ + { + name: `TOTP (Time-based One-time Password)`, + value: 'totp' + }, + { + name: `E-mail`, + value: 'email' + }, + { + name: `Phone (SMS)`, + value: 'phone' + }, + { + name: `Recovery code`, + value: 'recoveryCode' + } + ].filter((ch) => factors[ch.value] === true); + + return choices; + } + } +]; + +const questionsMfaChallenge = [ + { + type: "input", + name: "otp", + message: "Enter OTP", + validate(value) { + if (!value) { + return "Please enter OTP"; + } + return true; + }, + } +]; module.exports = { questionsInitProject, @@ -398,5 +451,7 @@ module.exports = { questionsDeployCollections, questionsDeployBuckets, questionsDeployTeams, - questionsGetEntrypoint + questionsGetEntrypoint, + questionsListFactors, + questionsMfaChallenge };