@@ -71,7 +71,15 @@ enum SMTPAuthType {
71
71
none,
72
72
plain,
73
73
login,
74
- cramMd5
74
+ cramMd5,
75
+ // / Authenticate using XOAUTH2 protocol
76
+ // /
77
+ // / Works for GMail and Office 365
78
+ // /
79
+ // / See_Also:
80
+ // / - https://developers.google.com/gmail/imap/xoauth2-protocol#using_oauth_20
81
+ // / - https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
82
+ xoauth2,
75
83
}
76
84
77
85
@@ -191,6 +199,19 @@ void sendMail(in SMTPClientSettings settings, Mail mail)
191
199
conn.write(Base64.encode(cast (const (ubyte )[])settings.password) ~ " \r\n " );
192
200
expectStatus(conn, 235 , " login password" );
193
201
break ;
202
+ case SMTPAuthType.xoauth2:
203
+ // Ideally we should inspect the server's capabilities instead of
204
+ // making this decision, but since the RFC for OAuth requires TLS,
205
+ // be a bit conservative.
206
+ enforce(settings.connectionType != SMTPConnectionType.plain,
207
+ " Cannot use XOAUTH2 without TLS" );
208
+ conn.write(" AUTH XOAUTH2\r\n " );
209
+ expectStatus(conn, SMTPStatus.serverAuthReady, " AUTH XOAUTH2" );
210
+ const authStr = " user=%s\1 auth=Bearer %s\1\1 " .format(
211
+ settings.username, settings.password);
212
+ conn.write(Base64.encode(authStr.representation) ~ " \r\n " );
213
+ expectStatus(conn, 235 , " XOAUTH2 authentication" );
214
+ break ;
194
215
case SMTPAuthType.cramMd5: assert (false , " TODO!" );
195
216
}
196
217
0 commit comments