mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 01:03:35 +00:00
[SG-515] add fastmail integration for generator (#3318)
* add fastmail integration for generator * prettier * introduce forwarder interface and implementations
This commit is contained in:
@@ -2,6 +2,13 @@ import { ApiService } from "../abstractions/api.service";
|
||||
import { CryptoService } from "../abstractions/crypto.service";
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
import { UsernameGenerationService as BaseUsernameGenerationService } from "../abstractions/usernameGeneration.service";
|
||||
import { AnonAddyForwarder } from "../emailForwarders/anonAddyForwarder";
|
||||
import { DuckDuckGoForwarder } from "../emailForwarders/duckDuckGoForwarder";
|
||||
import { FastmailForwarder } from "../emailForwarders/fastmailForwarder";
|
||||
import { FirefoxRelayForwarder } from "../emailForwarders/firefoxRelayForwarder";
|
||||
import { Forwarder } from "../emailForwarders/forwarder";
|
||||
import { ForwarderOptions } from "../emailForwarders/forwarderOptions";
|
||||
import { SimpleLoginForwarder } from "../emailForwarders/simpleLoginForwarder";
|
||||
import { EEFLongWordList } from "../misc/wordlist";
|
||||
|
||||
const DefaultOptions = {
|
||||
@@ -108,38 +115,33 @@ export class UsernameGenerationService implements BaseUsernameGenerationService
|
||||
return null;
|
||||
}
|
||||
|
||||
let forwarder: Forwarder = null;
|
||||
const forwarderOptions = new ForwarderOptions();
|
||||
forwarderOptions.website = o.website;
|
||||
if (o.forwardedService === "simplelogin") {
|
||||
if (o.forwardedSimpleLoginApiKey == null || o.forwardedSimpleLoginApiKey === "") {
|
||||
return null;
|
||||
}
|
||||
return this.generateSimpleLoginAlias(o.forwardedSimpleLoginApiKey, o.website);
|
||||
forwarder = new SimpleLoginForwarder();
|
||||
forwarderOptions.apiKey = o.forwardedSimpleLoginApiKey;
|
||||
} else if (o.forwardedService === "anonaddy") {
|
||||
if (
|
||||
o.forwardedAnonAddyApiToken == null ||
|
||||
o.forwardedAnonAddyApiToken === "" ||
|
||||
o.forwardedAnonAddyDomain == null ||
|
||||
o.forwardedAnonAddyDomain == ""
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return this.generateAnonAddyAlias(
|
||||
o.forwardedAnonAddyApiToken,
|
||||
o.forwardedAnonAddyDomain,
|
||||
o.website
|
||||
);
|
||||
forwarder = new AnonAddyForwarder();
|
||||
forwarderOptions.apiKey = o.forwardedAnonAddyApiToken;
|
||||
forwarderOptions.anonaddy.domain = o.forwardedAnonAddyDomain;
|
||||
} else if (o.forwardedService === "firefoxrelay") {
|
||||
if (o.forwardedFirefoxApiToken == null || o.forwardedFirefoxApiToken === "") {
|
||||
return null;
|
||||
}
|
||||
return this.generateFirefoxRelayAlias(o.forwardedFirefoxApiToken, o.website);
|
||||
forwarder = new FirefoxRelayForwarder();
|
||||
forwarderOptions.apiKey = o.forwardedFirefoxApiToken;
|
||||
} else if (o.forwardedService === "fastmail") {
|
||||
forwarder = new FastmailForwarder();
|
||||
forwarderOptions.apiKey = o.forwardedFastmailApiToken;
|
||||
forwarderOptions.fastmail.accountId = o.forwardedFastmailAccountId;
|
||||
} else if (o.forwardedService === "duckduckgo") {
|
||||
if (o.forwardedDuckDuckGoToken == null || o.forwardedDuckDuckGoToken === "") {
|
||||
return null;
|
||||
}
|
||||
return this.generateDuckDuckGoAlias(o.forwardedDuckDuckGoToken);
|
||||
forwarder = new DuckDuckGoForwarder();
|
||||
forwarderOptions.apiKey = o.forwardedDuckDuckGoToken;
|
||||
}
|
||||
|
||||
return null;
|
||||
if (forwarder == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return forwarder.generate(this.apiService, forwarderOptions);
|
||||
}
|
||||
|
||||
async getOptions(): Promise<any> {
|
||||
@@ -173,137 +175,4 @@ export class UsernameGenerationService implements BaseUsernameGenerationService
|
||||
? number
|
||||
: new Array(width - number.length + 1).join("0") + number;
|
||||
}
|
||||
|
||||
private async generateSimpleLoginAlias(apiKey: string, website: string): Promise<string> {
|
||||
if (apiKey == null || apiKey === "") {
|
||||
throw "Invalid SimpleLogin API key.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authentication: apiKey,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
let url = "https://app.simplelogin.io/api/alias/random/new";
|
||||
if (website != null) {
|
||||
url += "?hostname=" + website;
|
||||
}
|
||||
requestInit.body = JSON.stringify({
|
||||
note: (website != null ? "Website: " + website + ". " : "") + "Generated by Bitwarden.",
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await this.apiService.nativeFetch(request);
|
||||
if (response.status === 200 || response.status === 201) {
|
||||
const json = await response.json();
|
||||
return json.alias;
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw "Invalid SimpleLogin API key.";
|
||||
}
|
||||
try {
|
||||
const json = await response.json();
|
||||
if (json?.error != null) {
|
||||
throw "SimpleLogin error:" + json.error;
|
||||
}
|
||||
} catch {
|
||||
// Do nothing...
|
||||
}
|
||||
throw "Unknown SimpleLogin error occurred.";
|
||||
}
|
||||
|
||||
private async generateAnonAddyAlias(
|
||||
apiToken: string,
|
||||
domain: string,
|
||||
websiteNote: string
|
||||
): Promise<string> {
|
||||
if (apiToken == null || apiToken === "") {
|
||||
throw "Invalid AnonAddy API token.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Bearer " + apiToken,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://app.anonaddy.com/api/v1/aliases";
|
||||
requestInit.body = JSON.stringify({
|
||||
domain: domain,
|
||||
description:
|
||||
(websiteNote != null ? "Website: " + websiteNote + ". " : "") + "Generated by Bitwarden.",
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await this.apiService.nativeFetch(request);
|
||||
if (response.status === 200 || response.status === 201) {
|
||||
const json = await response.json();
|
||||
return json?.data?.email;
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw "Invalid AnonAddy API token.";
|
||||
}
|
||||
throw "Unknown AnonAddy error occurred.";
|
||||
}
|
||||
|
||||
private async generateFirefoxRelayAlias(apiToken: string, website: string): Promise<string> {
|
||||
if (apiToken == null || apiToken === "") {
|
||||
throw "Invalid Firefox Relay API token.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Token " + apiToken,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://relay.firefox.com/api/v1/relayaddresses/";
|
||||
requestInit.body = JSON.stringify({
|
||||
enabled: true,
|
||||
generated_for: website,
|
||||
description: (website != null ? website + " - " : "") + "Generated by Bitwarden.",
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await this.apiService.nativeFetch(request);
|
||||
if (response.status === 200 || response.status === 201) {
|
||||
const json = await response.json();
|
||||
return json?.full_address;
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw "Invalid Firefox Relay API token.";
|
||||
}
|
||||
throw "Unknown Firefox Relay error occurred.";
|
||||
}
|
||||
|
||||
private async generateDuckDuckGoAlias(apiToken: string): Promise<string> {
|
||||
if (apiToken == null || apiToken === "") {
|
||||
throw "Invalid DuckDuckGo API token.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Bearer " + apiToken,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://quack.duckduckgo.com/api/email/addresses";
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await this.apiService.nativeFetch(request);
|
||||
if (response.status === 200 || response.status === 201) {
|
||||
const json = await response.json();
|
||||
if (json.address) {
|
||||
return `${json.address}@duck.com`;
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
throw "Invalid DuckDuckGo API token.";
|
||||
}
|
||||
throw "Unknown DuckDuckGo error occurred.";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user