From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/base/src/OAuth2Providers.jsm | 259 +++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 comm/mailnews/base/src/OAuth2Providers.jsm (limited to 'comm/mailnews/base/src/OAuth2Providers.jsm') diff --git a/comm/mailnews/base/src/OAuth2Providers.jsm b/comm/mailnews/base/src/OAuth2Providers.jsm new file mode 100644 index 0000000000..86300b2ead --- /dev/null +++ b/comm/mailnews/base/src/OAuth2Providers.jsm @@ -0,0 +1,259 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Details of supported OAuth2 Providers. + */ +var EXPORTED_SYMBOLS = ["OAuth2Providers"]; + +// When we add a Google mail account, ask for address book and calendar scopes +// as well. Then we can add an address book or calendar without asking again. +// +// Don't ask for all the scopes when adding an address book or calendar +// independently of the mail set-up process. If a mail account already exists, +// we already have a token, and if it doesn't the user is likely to be setting +// up an address book/calendar without wanting mail. +const GOOGLE_SCOPES = + "https://mail.google.com/ https://www.googleapis.com/auth/carddav https://www.googleapis.com/auth/calendar"; +const FASTMAIL_SCOPES = + "https://www.fastmail.com/dev/protocol-imap https://www.fastmail.com/dev/protocol-pop https://www.fastmail.com/dev/protocol-smtp https://www.fastmail.com/dev/protocol-carddav https://www.fastmail.com/dev/protocol-caldav"; +const COMCAST_SCOPES = "https://email.comcast.net/ profile openid"; + +/** + * Map of hostnames to [issuer, scope]. + */ +var kHostnames = new Map([ + ["imap.googlemail.com", ["accounts.google.com", GOOGLE_SCOPES]], + ["smtp.googlemail.com", ["accounts.google.com", GOOGLE_SCOPES]], + ["pop.googlemail.com", ["accounts.google.com", GOOGLE_SCOPES]], + ["imap.gmail.com", ["accounts.google.com", GOOGLE_SCOPES]], + ["smtp.gmail.com", ["accounts.google.com", GOOGLE_SCOPES]], + ["pop.gmail.com", ["accounts.google.com", GOOGLE_SCOPES]], + [ + "www.googleapis.com", + ["accounts.google.com", "https://www.googleapis.com/auth/carddav"], + ], + + ["imap.mail.ru", ["o2.mail.ru", "mail.imap"]], + ["smtp.mail.ru", ["o2.mail.ru", "mail.imap"]], + + ["imap.yandex.com", ["oauth.yandex.com", "mail:imap_full"]], + ["smtp.yandex.com", ["oauth.yandex.com", "mail:smtp"]], + + ["imap.mail.yahoo.com", ["login.yahoo.com", "mail-w"]], + ["pop.mail.yahoo.com", ["login.yahoo.com", "mail-w"]], + ["smtp.mail.yahoo.com", ["login.yahoo.com", "mail-w"]], + + ["imap.aol.com", ["login.aol.com", "mail-w"]], + ["pop.aol.com", ["login.aol.com", "mail-w"]], + ["smtp.aol.com", ["login.aol.com", "mail-w"]], + + [ + "outlook.office365.com", + [ + "login.microsoftonline.com", + "https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access", + ], + ], + [ + "smtp.office365.com", + [ + "login.microsoftonline.com", + "https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access", + ], + ], + + ["imap.fastmail.com", ["www.fastmail.com", FASTMAIL_SCOPES]], + ["pop.fastmail.com", ["www.fastmail.com", FASTMAIL_SCOPES]], + ["smtp.fastmail.com", ["www.fastmail.com", FASTMAIL_SCOPES]], + [ + "carddav.fastmail.com", + ["www.fastmail.com", "https://www.fastmail.com/dev/protocol-carddav"], + ], + + ["imap.comcast.net", ["comcast.net", COMCAST_SCOPES]], + ["pop.comcast.net", ["comcast.net", COMCAST_SCOPES]], + ["smtp.comcast.net", ["comcast.net", COMCAST_SCOPES]], + + // For testing purposes. + ["mochi.test", ["mochi.test", "test_scope"]], +]); + +/** + * Map of issuers to clientId, clientSecret, authorizationEndpoint, tokenEndpoint, + * and usePKCE (RFC7636). + * Issuer is a unique string for the organization that a Thunderbird account + * was registered at. + * + * For the moment these details are hard-coded, since dynamic client + * registration is not yet supported. Don't copy these values for your + * own application - register one for yourself! This code (and possibly even the + * registration itself) will disappear when this is switched to dynamic + * client registration. + */ +var kIssuers = new Map([ + [ + "accounts.google.com", + { + clientId: + "406964657835-aq8lmia8j95dhl1a2bvharmfk3t1hgqj.apps.googleusercontent.com", + clientSecret: "kSmqreRr0qwBWJgbf5Y-PjSU", + authorizationEndpoint: "https://accounts.google.com/o/oauth2/auth", + tokenEndpoint: "https://www.googleapis.com/oauth2/v3/token", + }, + ], + [ + "o2.mail.ru", + { + clientId: "thunderbird", + clientSecret: "I0dCAXrcaNFujaaY", + authorizationEndpoint: "https://o2.mail.ru/login", + tokenEndpoint: "https://o2.mail.ru/token", + }, + ], + [ + "oauth.yandex.com", + { + clientId: "2a00bba7374047a6ab79666485ffce31", + clientSecret: "3ded85b4ec574c2187a55dc49d361280", + authorizationEndpoint: "https://oauth.yandex.com/authorize", + tokenEndpoint: "https://oauth.yandex.com/token", + }, + ], + [ + "login.yahoo.com", + { + clientId: + "dj0yJmk9NUtCTWFMNVpTaVJmJmQ9WVdrOVJ6UjVTa2xJTXpRbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0yYw--", + clientSecret: "f2de6a30ae123cdbc258c15e0812799010d589cc", + authorizationEndpoint: "https://api.login.yahoo.com/oauth2/request_auth", + tokenEndpoint: "https://api.login.yahoo.com/oauth2/get_token", + }, + ], + [ + "login.aol.com", + { + clientId: + "dj0yJmk9OXRHc1FqZHRQYzVvJmQ9WVdrOU1UQnJOR0pvTjJrbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD02NQ--", + clientSecret: "79c1c11991d148ddd02a919000d69879942fc278", + authorizationEndpoint: "https://api.login.aol.com/oauth2/request_auth", + tokenEndpoint: "https://api.login.aol.com/oauth2/get_token", + }, + ], + + [ + "login.microsoftonline.com", + { + clientId: "9e5f94bc-e8a4-4e73-b8be-63364c29d753", // Application (client) ID + // https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols#endpoints + authorizationEndpoint: + "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", + tokenEndpoint: + "https://login.microsoftonline.com/common/oauth2/v2.0/token", + redirectionEndpoint: "https://localhost", + }, + ], + + [ + "www.fastmail.com", + { + clientId: "35f141ae", + authorizationEndpoint: "https://api.fastmail.com/oauth/authorize", + tokenEndpoint: "https://api.fastmail.com/oauth/refresh", + usePKCE: true, + }, + ], + + [ + "comcast.net", + { + clientId: "thunderbird-oauth", + clientSecret: "fc5d0a314549bb3d059e0cec751fa4bd40a9cc7b", + authorizationEndpoint: "https://oauth.xfinity.com/oauth/authorize", + tokenEndpoint: "https://oauth.xfinity.com/oauth/token", + usePKCE: true, + }, + ], + + // For testing purposes. + [ + "mochi.test", + { + clientId: "test_client_id", + clientSecret: "test_secret", + authorizationEndpoint: + "http://mochi.test:8888/browser/comm/mail/components/addrbook/test/browser/data/redirect_auto.sjs", + tokenEndpoint: + "http://mochi.test:8888/browser/comm/mail/components/addrbook/test/browser/data/token.sjs", + // I don't know why, but tests refuse to work with a plain HTTP endpoint + // (the request is redirected to HTTPS, which we're not listening to). + // Just use an HTTPS endpoint. + redirectionEndpoint: "https://localhost", + }, + ], +]); + +/** + * OAuth2Providers: Methods to lookup OAuth2 parameters for supported OAuth2 + * providers. + */ +var OAuth2Providers = { + /** + * Map a hostname to the relevant issuer and scope. + * + * @param {string} hostname - The hostname of the server. For example + * "imap.googlemail.com". + * + * @returns {Array} An array containing [issuer, scope] for the hostname, or + * undefined if not found. + * - issuer is a string representing the organization + * - scope is an OAuth2 parameter describing the required access level + */ + getHostnameDetails(hostname) { + // During CardDAV SRV autodiscovery, rfc6764#section-6 says: + // + // * The client will need to make authenticated HTTP requests to + // the service. Typically, a "user identifier" is required for + // some form of user/password authentication. When a user + // identifier is required, clients MUST first use the "mailbox" + // + // However macOS Contacts does not do this and just uses the "localpart" + // instead. To work around this bug, during SRV autodiscovery Fastmail + // returns SRV records of the form '0 1 443 d[0-9]+.carddav.fastmail.com.' + // which encodes the internal domainid of the queried SRV domain in the + // sub-domain of the Target (rfc2782) of the SRV result. This can + // then be extracted from the Host header on each DAV request, the + // original domain looked up and attached to the "localpart" to create + // a full "mailbox", allowing autodiscovery to just work for usernames + // in any domain including self hosted domains. + // + // So for this hostname -> issuer/scope lookup to work, we need to + // look not just at the hostname, but also any sub-domains of this + // hostname. + while (hostname.includes(".")) { + let foundHost = kHostnames.get(hostname); + if (foundHost) { + return foundHost; + } + hostname = hostname.replace(/^[^.]*[.]/, ""); + } + return undefined; + }, + + /** + * Map an issuer to OAuth2 account details. + * + * @param {string} issuer - The organization issuing OAuth2 parameters, e.g. + * "accounts.google.com". + * + * @returns {Array} An array containing [clientId, clientSecret, authorizationEndpoint, tokenEndpoint]. + * clientId and clientSecret are strings representing the account registered + * for Thunderbird with the organization. + * authorizationEndpoint and tokenEndpoint are url strings representing + * endpoints to access OAuth2 authentication. + */ + getIssuerDetails(issuer) { + return kIssuers.get(issuer); + }, +}; -- cgit v1.2.3