mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-23 15:29:29 +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": {
|
"apiKey": {
|
||||||
"message": "API Key"
|
"message": "API Key"
|
||||||
},
|
},
|
||||||
|
"accountId": {
|
||||||
|
"message": "Account ID",
|
||||||
|
"description": "ID is short for 'Identifier'"
|
||||||
|
},
|
||||||
"ssoKeyConnectorError": {
|
"ssoKeyConnectorError": {
|
||||||
"message": "Key Connector error: make sure Key Connector is available and working correctly."
|
"message": "Key Connector error: make sure Key Connector is available and working correctly."
|
||||||
},
|
},
|
||||||
|
@ -395,6 +395,28 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</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>
|
</div>
|
||||||
<div class="box" *ngIf="usernameOptions.type === 'subaddress'">
|
<div class="box" *ngIf="usernameOptions.type === 'subaddress'">
|
||||||
|
@ -428,6 +428,28 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</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>
|
</div>
|
||||||
<div class="box" *ngIf="usernameOptions.type === 'subaddress'" [hidden]="!showOptions">
|
<div class="box" *ngIf="usernameOptions.type === 'subaddress'" [hidden]="!showOptions">
|
||||||
|
@ -1982,6 +1982,10 @@
|
|||||||
"premiumSubcriptionRequired": {
|
"premiumSubcriptionRequired": {
|
||||||
"message": "Premium subscription required"
|
"message": "Premium subscription required"
|
||||||
},
|
},
|
||||||
|
"accountId": {
|
||||||
|
"message": "Account ID",
|
||||||
|
"description": "ID is short for 'Identifier'"
|
||||||
|
},
|
||||||
"organizationIsDisabled": {
|
"organizationIsDisabled": {
|
||||||
"message": "Organization is disabled."
|
"message": "Organization is disabled."
|
||||||
},
|
},
|
||||||
|
@ -343,6 +343,28 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</ng-container>
|
||||||
<div class="row" *ngIf="usernameOptions.type === 'subaddress'">
|
<div class="row" *ngIf="usernameOptions.type === 'subaddress'">
|
||||||
<div class="form-group col-4">
|
<div class="form-group col-4">
|
||||||
|
@ -5312,5 +5312,9 @@
|
|||||||
},
|
},
|
||||||
"numberOfUsers": {
|
"numberOfUsers": {
|
||||||
"message": "Number of users"
|
"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: "SimpleLogin", value: "simplelogin" },
|
||||||
{ name: "AnonAddy", value: "anonaddy" },
|
{ name: "AnonAddy", value: "anonaddy" },
|
||||||
{ name: "Firefox Relay", value: "firefoxrelay" },
|
{ name: "Firefox Relay", value: "firefoxrelay" },
|
||||||
|
{ name: "FastMail", value: "fastmail" },
|
||||||
{ name: "DuckDuckGo", value: "duckduckgo" },
|
{ 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 { CryptoService } from "../abstractions/crypto.service";
|
||||||
import { StateService } from "../abstractions/state.service";
|
import { StateService } from "../abstractions/state.service";
|
||||||
import { UsernameGenerationService as BaseUsernameGenerationService } from "../abstractions/usernameGeneration.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";
|
import { EEFLongWordList } from "../misc/wordlist";
|
||||||
|
|
||||||
const DefaultOptions = {
|
const DefaultOptions = {
|
||||||
@ -108,40 +115,35 @@ export class UsernameGenerationService implements BaseUsernameGenerationService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let forwarder: Forwarder = null;
|
||||||
|
const forwarderOptions = new ForwarderOptions();
|
||||||
|
forwarderOptions.website = o.website;
|
||||||
if (o.forwardedService === "simplelogin") {
|
if (o.forwardedService === "simplelogin") {
|
||||||
if (o.forwardedSimpleLoginApiKey == null || o.forwardedSimpleLoginApiKey === "") {
|
forwarder = new SimpleLoginForwarder();
|
||||||
return null;
|
forwarderOptions.apiKey = o.forwardedSimpleLoginApiKey;
|
||||||
}
|
|
||||||
return this.generateSimpleLoginAlias(o.forwardedSimpleLoginApiKey, o.website);
|
|
||||||
} else if (o.forwardedService === "anonaddy") {
|
} else if (o.forwardedService === "anonaddy") {
|
||||||
if (
|
forwarder = new AnonAddyForwarder();
|
||||||
o.forwardedAnonAddyApiToken == null ||
|
forwarderOptions.apiKey = o.forwardedAnonAddyApiToken;
|
||||||
o.forwardedAnonAddyApiToken === "" ||
|
forwarderOptions.anonaddy.domain = o.forwardedAnonAddyDomain;
|
||||||
o.forwardedAnonAddyDomain == null ||
|
|
||||||
o.forwardedAnonAddyDomain == ""
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.generateAnonAddyAlias(
|
|
||||||
o.forwardedAnonAddyApiToken,
|
|
||||||
o.forwardedAnonAddyDomain,
|
|
||||||
o.website
|
|
||||||
);
|
|
||||||
} else if (o.forwardedService === "firefoxrelay") {
|
} else if (o.forwardedService === "firefoxrelay") {
|
||||||
if (o.forwardedFirefoxApiToken == null || o.forwardedFirefoxApiToken === "") {
|
forwarder = new FirefoxRelayForwarder();
|
||||||
return null;
|
forwarderOptions.apiKey = o.forwardedFirefoxApiToken;
|
||||||
}
|
} else if (o.forwardedService === "fastmail") {
|
||||||
return this.generateFirefoxRelayAlias(o.forwardedFirefoxApiToken, o.website);
|
forwarder = new FastmailForwarder();
|
||||||
|
forwarderOptions.apiKey = o.forwardedFastmailApiToken;
|
||||||
|
forwarderOptions.fastmail.accountId = o.forwardedFastmailAccountId;
|
||||||
} else if (o.forwardedService === "duckduckgo") {
|
} else if (o.forwardedService === "duckduckgo") {
|
||||||
if (o.forwardedDuckDuckGoToken == null || o.forwardedDuckDuckGoToken === "") {
|
forwarder = new DuckDuckGoForwarder();
|
||||||
return null;
|
forwarderOptions.apiKey = o.forwardedDuckDuckGoToken;
|
||||||
}
|
|
||||||
return this.generateDuckDuckGoAlias(o.forwardedDuckDuckGoToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (forwarder == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return forwarder.generate(this.apiService, forwarderOptions);
|
||||||
|
}
|
||||||
|
|
||||||
async getOptions(): Promise<any> {
|
async getOptions(): Promise<any> {
|
||||||
let options = await this.stateService.getUsernameGenerationOptions();
|
let options = await this.stateService.getUsernameGenerationOptions();
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
@ -173,137 +175,4 @@ export class UsernameGenerationService implements BaseUsernameGenerationService
|
|||||||
? number
|
? number
|
||||||
: new Array(width - number.length + 1).join("0") + 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