@@ -280,6 +280,14 @@ public class MailSend extends Task implements RunnableTask<VoidOutput> {
280280 )
281281 private Property <Object > embeddedImages ;
282282
283+ @ Schema (
284+ title = "OAuth2 access token" ,
285+ description = "Used only when transportStrategy is SMTP_OAUTH2. " +
286+ "If provided, it will be used instead of password. " +
287+ "The password field is treated as an OAuth2 access token when using SMTP_OAUTH2."
288+ )
289+ protected Property <String > accessToken ;
290+
283291 @ Override
284292 public VoidOutput run (RunContext runContext ) throws Exception {
285293 Thread .currentThread ().setContextClassLoader (getClass ().getClassLoader ());
@@ -319,14 +327,33 @@ public VoidOutput run(RunContext runContext) throws Exception {
319327 Email email = builder .buildEmail ();
320328
321329 var rTrustedHosts = runContext .render (trustedHosts ).asList (String .class );
330+
331+ TransportStrategy rStrategy = runContext .render (transportStrategy ).as (TransportStrategy .class ).orElse (TransportStrategy .SMTPS );
332+ String rPassword = runContext .render (this .password ).as (String .class ).orElse (null );
333+ String rAccessToken = runContext .render (this .accessToken ).as (String .class ).orElse (null );
334+
335+ String credential ;
336+
337+ if (rStrategy == TransportStrategy .SMTP_OAUTH2 ) {
338+ credential = rAccessToken != null ? rAccessToken : rPassword ;
339+
340+ if (credential == null ) {
341+ throw new IllegalArgumentException (
342+ "When using SMTP_OAUTH2, either 'accessToken' or 'password' must be provided"
343+ );
344+ }
345+ } else {
346+ credential = rPassword ;
347+ }
348+
322349 var mailerBuilder = MailerBuilder
323350 .withSMTPServer (
324351 runContext .render (this .host ).as (String .class ).orElse (null ),
325352 runContext .render (this .port ).as (Integer .class ).orElse (null ),
326353 runContext .render (this .username ).as (String .class ).orElse (null ),
327- runContext . render ( this . password ). as ( String . class ). orElse ( null )
354+ credential
328355 )
329- .withTransportStrategy (runContext . render ( transportStrategy ). as ( TransportStrategy . class ). orElse ( TransportStrategy . SMTPS ) )
356+ .withTransportStrategy (rStrategy )
330357 .withSessionTimeout (runContext .render (sessionTimeout ).as (Integer .class ).orElse (10000 ))
331358 .verifyingServerIdentity (runContext .render (verifyServerIdentity ).as (Boolean .class ).orElse (true ));
332359
0 commit comments