@@ -49,6 +49,43 @@ pub(super) async fn run_scriptable_login_provider(
4949 complete_scriptable_login ( provider, account_label, options, input) . await
5050}
5151
52+ /// Run the normal Google OAuth flow when the caller is noninteractive but a
53+ /// browser is available. The scriptable flow is normally used in that
54+ /// environment to avoid prompts, but Google needs a live localhost callback
55+ /// listener or the browser lands on a confusing connection error page.
56+ pub ( super ) async fn run_automatic_google_login (
57+ provider_id : & str ,
58+ options : & LoginOptions ,
59+ ) -> Result < LoginFlowOutcome > {
60+ let tier = options
61+ . google_access_tier
62+ . unwrap_or ( auth:: google:: GmailAccessTier :: Full ) ;
63+ let tokens = auth:: google:: login ( tier, options. no_browser ) . await ?;
64+ let credentials_path = auth:: google:: credentials_path ( ) ?;
65+ let tokens_path = auth:: google:: tokens_path ( ) ?;
66+
67+ emit_scriptable_auth_success (
68+ options. json ,
69+ ScriptableAuthSuccess {
70+ status : "authenticated" ,
71+ provider : provider_id. to_string ( ) ,
72+ account_label : None ,
73+ credentials_path : Some ( credentials_path. display ( ) . to_string ( ) ) ,
74+ email : tokens. email . clone ( ) ,
75+ } ,
76+ ) ?;
77+ if !options. json {
78+ eprintln ! ( "\n Gmail setup complete!" ) ;
79+ if let Some ( email) = tokens. email {
80+ eprintln ! ( "Account: {}" , email) ;
81+ }
82+ eprintln ! ( "Access tier: {}" , tokens. tier. label( ) ) ;
83+ eprintln ! ( "Tokens saved to {}" , tokens_path. display( ) ) ;
84+ }
85+ crate :: telemetry:: record_auth_success ( provider_id, "oauth" ) ;
86+ Ok ( LoginFlowOutcome :: Completed )
87+ }
88+
5289pub ( super ) async fn start_scriptable_login (
5390 provider : LoginProviderDescriptor ,
5491 account_label : Option < & str > ,
0 commit comments