mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-18 14:39:21 +01: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:
parent
d8cb543645
commit
2a49824581
@ -1965,6 +1965,10 @@
|
||||
"apiKey": {
|
||||
"message": "API Key"
|
||||
},
|
||||
"accountId": {
|
||||
"message": "Account ID",
|
||||
"description": "ID is short for 'Identifier'"
|
||||
},
|
||||
"ssoKeyConnectorError": {
|
||||
"message": "Key Connector error: make sure Key Connector is available and working correctly."
|
||||
},
|
||||
|
@ -395,6 +395,28 @@
|
||||
/>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="usernameOptions.forwardedService === 'fastmail'">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="fastmail-apiToken">{{ "apiAccessToken" | i18n }}</label>
|
||||
<input
|
||||
id="fastmail-apiToken"
|
||||
type="password"
|
||||
name="FastMailApiToken"
|
||||
[(ngModel)]="usernameOptions.forwardedFastmailApiToken"
|
||||
(blur)="saveUsernameOptions()"
|
||||
/>
|
||||
</div>
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="fastmail-accountId">{{ "accountId" | i18n }}</label>
|
||||
<input
|
||||
id="fastmail-accountId"
|
||||
type="text"
|
||||
name="FastmailAccountId"
|
||||
[(ngModel)]="usernameOptions.forwardedFastmailAccountId"
|
||||
(blur)="saveUsernameOptions()"
|
||||
/>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box" *ngIf="usernameOptions.type === 'subaddress'">
|
||||
|
@ -428,6 +428,28 @@
|
||||
/>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="usernameOptions.forwardedService === 'fastmail'">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="fastmail-apiToken">{{ "apiAccessToken" | i18n }}</label>
|
||||
<input
|
||||
id="fastmail-apiToken"
|
||||
type="password"
|
||||
name="FastMailApiToken"
|
||||
[(ngModel)]="usernameOptions.forwardedFastmailApiToken"
|
||||
(blur)="saveUsernameOptions()"
|
||||
/>
|
||||
</div>
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="fastmail-accountId">{{ "accountId" | i18n }}</label>
|
||||
<input
|
||||
id="fastmail-accountId"
|
||||
type="text"
|
||||
name="FastmailAccountId"
|
||||
[(ngModel)]="usernameOptions.forwardedFastmailAccountId"
|
||||
(blur)="saveUsernameOptions()"
|
||||
/>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box" *ngIf="usernameOptions.type === 'subaddress'" [hidden]="!showOptions">
|
||||
|
@ -1982,6 +1982,10 @@
|
||||
"premiumSubcriptionRequired": {
|
||||
"message": "Premium subscription required"
|
||||
},
|
||||
"accountId": {
|
||||
"message": "Account ID",
|
||||
"description": "ID is short for 'Identifier'"
|
||||
},
|
||||
"organizationIsDisabled": {
|
||||
"message": "Organization is disabled."
|
||||
},
|
||||
|
@ -343,6 +343,28 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" *ngIf="usernameOptions.forwardedService === 'fastmail'">
|
||||
<div class="form-group col-4">
|
||||
<label for="fastmail-apiToken">{{ "apiAccessToken" | i18n }}</label>
|
||||
<input
|
||||
id="fastmail-apiToken"
|
||||
class="form-control"
|
||||
type="password"
|
||||
[(ngModel)]="usernameOptions.forwardedFastmailApiToken"
|
||||
(blur)="saveUsernameOptions()"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group col-4">
|
||||
<label for="fastmail-accountId">{{ "accountId" | i18n }}</label>
|
||||
<input
|
||||
id="fastmail-accountId"
|
||||
class="form-control"
|
||||
type="text"
|
||||
[(ngModel)]="usernameOptions.forwardedFastmailAccountId"
|
||||
(blur)="saveUsernameOptions()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div class="row" *ngIf="usernameOptions.type === 'subaddress'">
|
||||
<div class="form-group col-4">
|
||||
|
@ -5312,5 +5312,9 @@
|
||||
},
|
||||
"numberOfUsers": {
|
||||
"message": "Number of users"
|
||||
},
|
||||
"accountId": {
|
||||
"message": "Account ID",
|
||||
"description": "ID is short for 'Identifier'"
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ export class GeneratorComponent implements OnInit {
|
||||
{ name: "SimpleLogin", value: "simplelogin" },
|
||||
{ name: "AnonAddy", value: "anonaddy" },
|
||||
{ name: "Firefox Relay", value: "firefoxrelay" },
|
||||
{ name: "FastMail", value: "fastmail" },
|
||||
{ name: "DuckDuckGo", value: "duckduckgo" },
|
||||
// { name: "FastMail", value: "fastmail" },
|
||||
];
|
||||
}
|
||||
|
||||
|
41
libs/common/src/emailForwarders/anonAddyForwarder.ts
Normal file
41
libs/common/src/emailForwarders/anonAddyForwarder.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { ApiService } from "../abstractions/api.service";
|
||||
|
||||
import { Forwarder } from "./forwarder";
|
||||
import { ForwarderOptions } from "./forwarderOptions";
|
||||
|
||||
export class AnonAddyForwarder implements Forwarder {
|
||||
async generate(apiService: ApiService, options: ForwarderOptions): Promise<string> {
|
||||
if (options.apiKey == null || options.apiKey === "") {
|
||||
throw "Invalid AnonAddy API token.";
|
||||
}
|
||||
if (options.anonaddy?.domain == null || options.anonaddy.domain === "") {
|
||||
throw "Invalid AnonAddy domain.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Bearer " + options.apiKey,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://app.anonaddy.com/api/v1/aliases";
|
||||
requestInit.body = JSON.stringify({
|
||||
domain: options.anonaddy.domain,
|
||||
description:
|
||||
(options.website != null ? "Website: " + options.website + ". " : "") +
|
||||
"Generated by Bitwarden.",
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await 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.";
|
||||
}
|
||||
}
|
33
libs/common/src/emailForwarders/duckDuckGoForwarder.ts
Normal file
33
libs/common/src/emailForwarders/duckDuckGoForwarder.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { ApiService } from "../abstractions/api.service";
|
||||
|
||||
import { Forwarder } from "./forwarder";
|
||||
import { ForwarderOptions } from "./forwarderOptions";
|
||||
|
||||
export class DuckDuckGoForwarder implements Forwarder {
|
||||
async generate(apiService: ApiService, options: ForwarderOptions): Promise<string> {
|
||||
if (options.apiKey == null || options.apiKey === "") {
|
||||
throw "Invalid DuckDuckGo API token.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Bearer " + options.apiKey,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://quack.duckduckgo.com/api/email/addresses";
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await 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.";
|
||||
}
|
||||
}
|
67
libs/common/src/emailForwarders/fastmailForwarder.ts
Normal file
67
libs/common/src/emailForwarders/fastmailForwarder.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { ApiService } from "../abstractions/api.service";
|
||||
|
||||
import { Forwarder } from "./forwarder";
|
||||
import { ForwarderOptions } from "./forwarderOptions";
|
||||
|
||||
export class FastmailForwarder implements Forwarder {
|
||||
async generate(apiService: ApiService, options: ForwarderOptions): Promise<string> {
|
||||
if (options.apiKey == null || options.apiKey === "") {
|
||||
throw "Invalid Fastmail API token.";
|
||||
}
|
||||
if (options?.fastmail.accountId == null || options.fastmail.accountId === "") {
|
||||
throw "Invalid Fastmail account ID.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Bearer " + options.apiKey,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://api.fastmail.com/jmap/api/";
|
||||
requestInit.body = JSON.stringify({
|
||||
using: ["https://www.fastmail.com/dev/maskedemail", "urn:ietf:params:jmap:core"],
|
||||
methodCalls: [
|
||||
[
|
||||
"MaskedEmail/set",
|
||||
{
|
||||
accountId: "u" + options.fastmail.accountId,
|
||||
create: {
|
||||
"new-masked-email": {
|
||||
state: "enabled",
|
||||
description:
|
||||
(options.website != null ? options.website + " - " : "") +
|
||||
"Generated by Bitwarden",
|
||||
url: options.website,
|
||||
emailPrefix: options.fastmail.prefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
"0",
|
||||
],
|
||||
],
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await apiService.nativeFetch(request);
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
if (
|
||||
json.methodResponses != null &&
|
||||
json.methodResponses.length > 0 &&
|
||||
json.methodResponses[0].length > 0
|
||||
) {
|
||||
if (json.methodResponses[0][0] === "MaskedEmail/set") {
|
||||
return json.methodResponses[0][1]?.created?.["new-masked-email"]?.email;
|
||||
} else if (json.methodResponses[0][0] === "error") {
|
||||
throw "Fastmail error: " + json.methodResponses[0][1]?.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw "Invalid Fastmail API token.";
|
||||
}
|
||||
throw "Unknown Fastmail error occurred.";
|
||||
}
|
||||
}
|
38
libs/common/src/emailForwarders/firefoxRelayForwarder.ts
Normal file
38
libs/common/src/emailForwarders/firefoxRelayForwarder.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { ApiService } from "../abstractions/api.service";
|
||||
|
||||
import { Forwarder } from "./forwarder";
|
||||
import { ForwarderOptions } from "./forwarderOptions";
|
||||
|
||||
export class FirefoxRelayForwarder implements Forwarder {
|
||||
async generate(apiService: ApiService, options: ForwarderOptions): Promise<string> {
|
||||
if (options.apiKey == null || options.apiKey === "") {
|
||||
throw "Invalid Firefox Relay API token.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authorization: "Token " + options.apiKey,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
const url = "https://relay.firefox.com/api/v1/relayaddresses/";
|
||||
requestInit.body = JSON.stringify({
|
||||
enabled: true,
|
||||
generated_for: options.website,
|
||||
description:
|
||||
(options.website != null ? options.website + " - " : "") + "Generated by Bitwarden.",
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await 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.";
|
||||
}
|
||||
}
|
7
libs/common/src/emailForwarders/forwarder.ts
Normal file
7
libs/common/src/emailForwarders/forwarder.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { ApiService } from "../abstractions/api.service";
|
||||
|
||||
import { ForwarderOptions } from "./forwarderOptions";
|
||||
|
||||
export interface Forwarder {
|
||||
generate(apiService: ApiService, options: ForwarderOptions): Promise<string>;
|
||||
}
|
15
libs/common/src/emailForwarders/forwarderOptions.ts
Normal file
15
libs/common/src/emailForwarders/forwarderOptions.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export class ForwarderOptions {
|
||||
apiKey: string;
|
||||
website: string;
|
||||
fastmail = new FastmailForwarderOptions();
|
||||
anonaddy = new AnonAddyForwarderOptions();
|
||||
}
|
||||
|
||||
export class FastmailForwarderOptions {
|
||||
accountId: string;
|
||||
prefix: string;
|
||||
}
|
||||
|
||||
export class AnonAddyForwarderOptions {
|
||||
domain: string;
|
||||
}
|
48
libs/common/src/emailForwarders/simpleLoginForwarder.ts
Normal file
48
libs/common/src/emailForwarders/simpleLoginForwarder.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { ApiService } from "../abstractions/api.service";
|
||||
|
||||
import { Forwarder } from "./forwarder";
|
||||
import { ForwarderOptions } from "./forwarderOptions";
|
||||
|
||||
export class SimpleLoginForwarder implements Forwarder {
|
||||
async generate(apiService: ApiService, options: ForwarderOptions): Promise<string> {
|
||||
if (options.apiKey == null || options.apiKey === "") {
|
||||
throw "Invalid SimpleLogin API key.";
|
||||
}
|
||||
const requestInit: RequestInit = {
|
||||
redirect: "manual",
|
||||
cache: "no-store",
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
Authentication: options.apiKey,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
};
|
||||
let url = "https://app.simplelogin.io/api/alias/random/new";
|
||||
if (options.website != null) {
|
||||
url += "?hostname=" + options.website;
|
||||
}
|
||||
requestInit.body = JSON.stringify({
|
||||
note:
|
||||
(options.website != null ? "Website: " + options.website + ". " : "") +
|
||||
"Generated by Bitwarden.",
|
||||
});
|
||||
const request = new Request(url, requestInit);
|
||||
const response = await 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.";
|
||||
}
|
||||
}
|
@ -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.";
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user