@@ -10,7 +10,7 @@ import {
1010 messageHandler ,
1111} from '@contentstack/cli-utilities' ;
1212import { User } from '../../interfaces' ;
13- import { authHandler , interactive } from '../../utils' ;
13+ import { authHandler , interactive , mfaHandler } from '../../utils' ;
1414import { BaseCommand } from '../../base-command' ;
1515
1616export default class LoginCommand extends BaseCommand < typeof LoginCommand > {
@@ -40,6 +40,7 @@ export default class LoginCommand extends BaseCommand<typeof LoginCommand> {
4040 required : false ,
4141 exclusive : [ 'oauth' ] ,
4242 } ) ,
43+
4344 oauth : flags . boolean ( {
4445 description : 'Enables single sign-on (SSO) in Contentstack CLI.' ,
4546 required : false ,
@@ -57,9 +58,9 @@ export default class LoginCommand extends BaseCommand<typeof LoginCommand> {
5758 log . debug ( 'Initializing management API client' , this . contextDetails ) ;
5859 const managementAPIClient = await managementSDKClient ( { host : this . cmaHost , skipTokenValidity : true } ) ;
5960 log . debug ( 'Management API client initialized successfully' , this . contextDetails ) ;
60-
61+
6162 const { flags : loginFlags } = await this . parse ( LoginCommand ) ;
62- log . debug ( 'Token add flags parsed' , { ...this . contextDetails , flags : loginFlags } ) ;
63+ log . debug ( 'Token add flags parsed' , { ...this . contextDetails , flags : loginFlags } ) ;
6364
6465 authHandler . client = managementAPIClient ;
6566 log . debug ( 'Auth handler client set' , this . contextDetails ) ;
@@ -76,12 +77,22 @@ export default class LoginCommand extends BaseCommand<typeof LoginCommand> {
7677 log . debug ( 'Starting basic authentication flow' , this . contextDetails ) ;
7778 const username = loginFlags ?. username || ( await interactive . askUsername ( ) ) ;
7879 const password = loginFlags ?. password || ( await interactive . askPassword ( ) ) ;
79- log . debug ( 'Credentials obtained' , { ...this . contextDetails , hasUsername : ! ! username , hasPassword : ! ! password } ) ;
80+ log . debug ( 'Credentials obtained' , {
81+ ...this . contextDetails ,
82+ hasUsername : ! ! username ,
83+ hasPassword : ! ! password ,
84+ } ) ;
85+
8086 await this . login ( username , password ) ;
8187 }
8288 } catch ( error ) {
83- log . debug ( 'Login command failed' , { ...this . contextDetails , error } ) ;
84- cliux . error ( 'CLI_AUTH_LOGIN_FAILED' ) ;
89+ log . debug ( 'Login command failed' , {
90+ ...this . contextDetails ,
91+ error,
92+ } ) ;
93+ if ( ( error ?. message && error ?. message . includes ( '2FA' ) ) || error ?. message . includes ( 'MFA' ) ) {
94+ error . message = `${ error . message } \nFor more information about MFA, visit: https://www.contentstack.com/docs/developers/security/multi-factor-authentication` ;
95+ }
8596 handleAndLogError ( error , { ...this . contextDetails } ) ;
8697 process . exit ( ) ;
8798 }
@@ -92,7 +103,19 @@ export default class LoginCommand extends BaseCommand<typeof LoginCommand> {
92103
93104 try {
94105 log . debug ( 'Calling auth handler login' , this . contextDetails ) ;
95- const user : User = await authHandler . login ( username , password ) ;
106+ let tfaToken : string | undefined ;
107+
108+ try {
109+ tfaToken = await mfaHandler . getMFACode ( ) ;
110+ if ( tfaToken ) {
111+ log . debug ( 'MFA token generated from stored configuration' , this . contextDetails ) ;
112+ }
113+ } catch ( error ) {
114+ log . debug ( 'Failed to generate MFA token from config' , { ...this . contextDetails , error } ) ;
115+ tfaToken = undefined ;
116+ }
117+
118+ const user : User = await authHandler . login ( username , password , tfaToken ) ;
96119 log . debug ( 'Auth handler login completed' , {
97120 ...this . contextDetails ,
98121 hasUser : ! ! user ,
0 commit comments