mirror of
https://github.com/bitwarden/server.git
synced 2025-02-09 00:41:37 +01:00
remove mail and function projects
This commit is contained in:
parent
740453c900
commit
580e9e51e5
@ -27,8 +27,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Api", "src\Api\Api.csproj",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "Sql", "src\Sql\Sql.sqlproj", "{58554E52-FDEC-4832-AFF9-302B01E08DCA}"
|
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "Sql", "src\Sql\Sql.sqlproj", "{58554E52-FDEC-4832-AFF9-302B01E08DCA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mail", "util\Mail\Mail.csproj", "{B78A6C74-1A24-48C6-802A-13BE3E4DAFF1}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Billing", "src\Billing\Billing.csproj", "{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Billing", "src\Billing\Billing.csproj", "{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity", "src\Identity\Identity.csproj", "{04148736-3C0B-445E-8B74-2020E7A53502}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity", "src\Identity\Identity.csproj", "{04148736-3C0B-445E-8B74-2020E7A53502}"
|
||||||
@ -37,8 +35,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Setup", "util\Setup\Setup.c
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "util\Server\Server.csproj", "{66B0A682-658A-4A82-B606-A077A4871448}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "util\Server\Server.csproj", "{66B0A682-658A-4A82-B606-A077A4871448}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Function", "util\Function\Function.csproj", "{A6C44A84-8E51-4C64-B9C4-7B7C23253345}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Icons", "src\Icons\Icons.csproj", "{9CF59342-3912-4B45-A2BA-0F173666586D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Icons", "src\Icons\Icons.csproj", "{9CF59342-3912-4B45-A2BA-0F173666586D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Events", "src\Events\Events.csproj", "{994DD611-F266-4BD3-8072-3B1B57267ED5}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Events", "src\Events\Events.csproj", "{994DD611-F266-4BD3-8072-3B1B57267ED5}"
|
||||||
@ -69,10 +65,6 @@ Global
|
|||||||
{58554E52-FDEC-4832-AFF9-302B01E08DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{58554E52-FDEC-4832-AFF9-302B01E08DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{58554E52-FDEC-4832-AFF9-302B01E08DCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{58554E52-FDEC-4832-AFF9-302B01E08DCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{58554E52-FDEC-4832-AFF9-302B01E08DCA}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
{58554E52-FDEC-4832-AFF9-302B01E08DCA}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
{B78A6C74-1A24-48C6-802A-13BE3E4DAFF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B78A6C74-1A24-48C6-802A-13BE3E4DAFF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B78A6C74-1A24-48C6-802A-13BE3E4DAFF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B78A6C74-1A24-48C6-802A-13BE3E4DAFF1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -89,10 +81,6 @@ Global
|
|||||||
{66B0A682-658A-4A82-B606-A077A4871448}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{66B0A682-658A-4A82-B606-A077A4871448}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{66B0A682-658A-4A82-B606-A077A4871448}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{66B0A682-658A-4A82-B606-A077A4871448}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{66B0A682-658A-4A82-B606-A077A4871448}.Release|Any CPU.Build.0 = Release|Any CPU
|
{66B0A682-658A-4A82-B606-A077A4871448}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{A6C44A84-8E51-4C64-B9C4-7B7C23253345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{A6C44A84-8E51-4C64-B9C4-7B7C23253345}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{A6C44A84-8E51-4C64-B9C4-7B7C23253345}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{A6C44A84-8E51-4C64-B9C4-7B7C23253345}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{9CF59342-3912-4B45-A2BA-0F173666586D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{9CF59342-3912-4B45-A2BA-0F173666586D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{9CF59342-3912-4B45-A2BA-0F173666586D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{9CF59342-3912-4B45-A2BA-0F173666586D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{9CF59342-3912-4B45-A2BA-0F173666586D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{9CF59342-3912-4B45-A2BA-0F173666586D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -121,12 +109,10 @@ Global
|
|||||||
{3973D21B-A692-4B60-9B70-3631C057423A} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{3973D21B-A692-4B60-9B70-3631C057423A} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{E8548AD6-7FB0-439A-8EB5-549A10336D2D} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{E8548AD6-7FB0-439A-8EB5-549A10336D2D} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{58554E52-FDEC-4832-AFF9-302B01E08DCA} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{58554E52-FDEC-4832-AFF9-302B01E08DCA} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{B78A6C74-1A24-48C6-802A-13BE3E4DAFF1} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
|
||||||
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{02BC2982-ED8D-4A6D-A41E-092B3DAEB98A} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{04148736-3C0B-445E-8B74-2020E7A53502} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{04148736-3C0B-445E-8B74-2020E7A53502} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{EF2164EF-1FC0-4518-A2ED-CE02D3630B00} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
{EF2164EF-1FC0-4518-A2ED-CE02D3630B00} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
||||||
{66B0A682-658A-4A82-B606-A077A4871448} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
{66B0A682-658A-4A82-B606-A077A4871448} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
||||||
{A6C44A84-8E51-4C64-B9C4-7B7C23253345} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E}
|
|
||||||
{9CF59342-3912-4B45-A2BA-0F173666586D} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{9CF59342-3912-4B45-A2BA-0F173666586D} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{994DD611-F266-4BD3-8072-3B1B57267ED5} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{994DD611-F266-4BD3-8072-3B1B57267ED5} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{2235D24F-E607-47F4-81AD-BB4504ADF9C6} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{2235D24F-E607-47F4-81AD-BB4504ADF9C6} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.Function.Models;
|
|
||||||
using Microsoft.Azure.WebJobs;
|
|
||||||
using Microsoft.Azure.WebJobs.Host;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Function
|
|
||||||
{
|
|
||||||
public static class BlockIp
|
|
||||||
{
|
|
||||||
[FunctionName("BlockIp")]
|
|
||||||
public static void Run(
|
|
||||||
[QueueTrigger("blockip", Connection = "")]string myQueueItem,
|
|
||||||
out string outputQueueItem,
|
|
||||||
TraceWriter log)
|
|
||||||
{
|
|
||||||
outputQueueItem = BlockIpAsync(myQueueItem).GetAwaiter().GetResult();
|
|
||||||
log.Info($"C# Queue trigger function processed: {myQueueItem}, outputted: {outputQueueItem}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<string> BlockIpAsync(string ipAddress)
|
|
||||||
{
|
|
||||||
var ipWhitelist = ConfigurationManager.AppSettings["WhitelistedIps"];
|
|
||||||
if(ipWhitelist != null && ipWhitelist.Split(',').Contains(ipAddress))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var xAuthEmail = ConfigurationManager.AppSettings["X-Auth-Email"];
|
|
||||||
var xAuthKey = ConfigurationManager.AppSettings["X-Auth-Key"];
|
|
||||||
var zoneId = ConfigurationManager.AppSettings["ZoneId"];
|
|
||||||
|
|
||||||
using(var client = new HttpClient())
|
|
||||||
{
|
|
||||||
client.BaseAddress = new Uri("https://api.cloudflare.com");
|
|
||||||
client.DefaultRequestHeaders.Accept.Clear();
|
|
||||||
client.DefaultRequestHeaders.Add("X-Auth-Email", xAuthEmail);
|
|
||||||
client.DefaultRequestHeaders.Add("X-Auth-Key", xAuthKey);
|
|
||||||
|
|
||||||
var response = await client.PostAsJsonAsync(
|
|
||||||
$"/client/v4/zones/{zoneId}/firewall/access_rules/rules",
|
|
||||||
new
|
|
||||||
{
|
|
||||||
mode = "block",
|
|
||||||
configuration = new
|
|
||||||
{
|
|
||||||
target = "ip",
|
|
||||||
value = ipAddress
|
|
||||||
},
|
|
||||||
notes = $"Rate limit abuse on {DateTime.UtcNow.ToString()}."
|
|
||||||
});
|
|
||||||
|
|
||||||
var responseString = await response.Content.ReadAsStringAsync();
|
|
||||||
var responseJson = JsonConvert.DeserializeObject<AccessRuleResponse>(responseString);
|
|
||||||
|
|
||||||
if(!responseJson.Success)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncomment whenever we can delay the returned message. Functions do not support that at this time.
|
|
||||||
return null; //responseJson.Result?.Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Data;
|
|
||||||
using System.Data.SqlClient;
|
|
||||||
using Microsoft.Azure.WebJobs;
|
|
||||||
using Microsoft.Azure.WebJobs.Host;
|
|
||||||
|
|
||||||
namespace Bit.Function
|
|
||||||
{
|
|
||||||
public static class DatabaseMaintenance
|
|
||||||
{
|
|
||||||
[FunctionName("DatabaseMaintenance")]
|
|
||||||
public static void Run([TimerTrigger("0 0 4 * * *")]TimerInfo myTimer, TraceWriter log)
|
|
||||||
{
|
|
||||||
var connectionString = ConfigurationManager.ConnectionStrings["Vault"].ConnectionString;
|
|
||||||
using(var connection = new SqlConnection(connectionString))
|
|
||||||
{
|
|
||||||
connection.Open();
|
|
||||||
|
|
||||||
// ref: http://bit.ly/2zFNcZo
|
|
||||||
var cmd = new SqlCommand("[dbo].[AzureSQLMaintenance]", connection)
|
|
||||||
{
|
|
||||||
CommandType = CommandType.StoredProcedure
|
|
||||||
};
|
|
||||||
|
|
||||||
// Options: "all", "index", "statistics"
|
|
||||||
cmd.Parameters.Add("@operation", SqlDbType.NVarChar).Value = "all";
|
|
||||||
// Options: "smart", "dummy"
|
|
||||||
cmd.Parameters.Add("@mode", SqlDbType.NVarChar).Value = "smart";
|
|
||||||
// Options: 0, 1
|
|
||||||
cmd.Parameters.Add("@LogToTable", SqlDbType.Bit).Value = 1;
|
|
||||||
|
|
||||||
// Asynchronous BeginExecuteNonQuery for this long running sproc to avoid timeouts
|
|
||||||
var result = cmd.BeginExecuteNonQuery();
|
|
||||||
cmd.EndExecuteNonQuery(result);
|
|
||||||
|
|
||||||
log.Info($"Started [dbo].[AzureSQLMaintenance] at {DateTime.UtcNow}.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,175 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using Microsoft.Azure.WebJobs;
|
|
||||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
|
||||||
using Microsoft.Azure.WebJobs.Host;
|
|
||||||
|
|
||||||
namespace Bit.Function
|
|
||||||
{
|
|
||||||
public static class Download
|
|
||||||
{
|
|
||||||
// Desktop
|
|
||||||
const string DesktopCurrentVersion = "0.0.7";
|
|
||||||
|
|
||||||
const string DesktopWindowsPortableFileName = "Bitwarden-Portable-{0}.exe";
|
|
||||||
const string DesktopWindowsWebInstallerFileName = "Bitwarden-Installer-{0}.exe";
|
|
||||||
const string DesktopWindowsAppxFileName = "Bitwarden-{0}.appx";
|
|
||||||
const string DesktopWindowsAppx32FileName = "Bitwarden-{0}-ia32.appx";
|
|
||||||
const string DesktopWindowsStoreUrl = "https://www.microsoft.com/en-us/store/b/home";
|
|
||||||
const string DesktopWindowsChocoUrl = "https://chocolatey.org/packages/bitwarden";
|
|
||||||
|
|
||||||
const string DesktopMacOsDmgFileName = "Bitwarden-{0}.dmg";
|
|
||||||
const string DesktopMacOsPkgFileName = "Bitwarden-{0}.pkg";
|
|
||||||
const string DesktopMacOsZipFileName = "bitwarden-{0}-mac.zip";
|
|
||||||
const string DesktopMacOsStoreUrl = "https://itunes.com";
|
|
||||||
const string DesktopMacOsCaskUrl = "https://caskroom.github.io/search";
|
|
||||||
|
|
||||||
const string DesktopLinuxAppImageFileName = "Bitwarden-{0}-x86_64.AppImage";
|
|
||||||
const string DesktopLinuxDebFileName = "Bitwarden-{0}-amd64.deb";
|
|
||||||
const string DesktopLinuxRpmFileName = "Bitwarden-{0}-x86_64.rpm";
|
|
||||||
const string DesktopLinuxFreeBsdFileName = "Bitwarden-{0}.freebsd";
|
|
||||||
const string DesktopLinuxSnapUrl = "https://snapcraft.io/";
|
|
||||||
|
|
||||||
// Browser
|
|
||||||
const string BrowserSafariFileUrl = "https://cdn.bitwarden.com/safari-extension/bitwarden-1.24.1.safariextz";
|
|
||||||
const string BrowserSafariStoreUrl = "https://safari-extensions.apple.com";
|
|
||||||
|
|
||||||
[FunctionName("Download")]
|
|
||||||
public static HttpResponseMessage Run(
|
|
||||||
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "api/download")]HttpRequestMessage req,
|
|
||||||
TraceWriter log)
|
|
||||||
{
|
|
||||||
var qs = req.GetQueryNameValuePairs();
|
|
||||||
var app = GetQsParam(qs, "app")?.ToLowerInvariant();
|
|
||||||
var platform = GetQsParam(qs, "platform")?.ToLowerInvariant();
|
|
||||||
var variant = GetQsParam(qs, "variant")?.ToLowerInvariant();
|
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(app))
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "'app' parameter is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(platform))
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "'platform' parameter is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(app == "desktop")
|
|
||||||
{
|
|
||||||
if(platform == "windows")
|
|
||||||
{
|
|
||||||
if(variant == null || variant == "exe" || variant == "web")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopWindowsWebInstallerFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "portable")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopWindowsPortableFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "appx")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopWindowsAppxFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "appx32")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopWindowsAppx32FileName);
|
|
||||||
}
|
|
||||||
else if(variant == "store")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, DesktopWindowsStoreUrl);
|
|
||||||
}
|
|
||||||
else if(variant == "choco")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, DesktopWindowsChocoUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(platform == "mac" || platform == "macos")
|
|
||||||
{
|
|
||||||
if(variant == null || variant == "dmg")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopMacOsDmgFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "pkg")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopMacOsPkgFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "zip")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopMacOsZipFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "store")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, DesktopMacOsStoreUrl);
|
|
||||||
}
|
|
||||||
else if(variant == "cask" || variant == "brew")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, DesktopMacOsCaskUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(platform == "linux")
|
|
||||||
{
|
|
||||||
if(variant == null || variant == "appimage")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopLinuxAppImageFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "deb")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopLinuxDebFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "rpm")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopLinuxRpmFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "freebsd")
|
|
||||||
{
|
|
||||||
return GetDesktopDownloadResponse(req, DesktopLinuxFreeBsdFileName);
|
|
||||||
}
|
|
||||||
else if(variant == "snap")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, DesktopLinuxSnapUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(app == "browser")
|
|
||||||
{
|
|
||||||
if(platform == "safari")
|
|
||||||
{
|
|
||||||
if(variant == null || variant == "safariextz")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, BrowserSafariFileUrl);
|
|
||||||
}
|
|
||||||
else if(variant == "store")
|
|
||||||
{
|
|
||||||
return GetRedirectResponse(req, BrowserSafariStoreUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return req.CreateResponse(HttpStatusCode.NotFound, "Download not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetQsParam(IEnumerable<KeyValuePair<string, string>> qs, string key)
|
|
||||||
{
|
|
||||||
return qs.FirstOrDefault(q => string.Compare(q.Key, key, true) == 0).Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpResponseMessage GetDesktopDownloadResponse(HttpRequestMessage req, string filename)
|
|
||||||
{
|
|
||||||
var filenameWithVersion = string.Format(filename, DesktopCurrentVersion);
|
|
||||||
var downloadUrl = string.Format("https://github.com/bitwarden/desktop/releases/download/v{0}/{1}",
|
|
||||||
DesktopCurrentVersion, filenameWithVersion);
|
|
||||||
return GetRedirectResponse(req, downloadUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpResponseMessage GetRedirectResponse(HttpRequestMessage req, string url)
|
|
||||||
{
|
|
||||||
var response = req.CreateResponse(HttpStatusCode.Redirect);
|
|
||||||
response.Headers.Location = new Uri(url);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net471</TargetFramework>
|
|
||||||
<RootNamespace>Bit.Function</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.14" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Configuration" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="host.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="local.settings.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.Azure.WebJobs;
|
|
||||||
using Microsoft.Azure.WebJobs.Host;
|
|
||||||
|
|
||||||
namespace Bit.Function
|
|
||||||
{
|
|
||||||
public static class KeepAlive
|
|
||||||
{
|
|
||||||
[FunctionName("KeepAlive")]
|
|
||||||
public static void Run([TimerTrigger("0 */15 * * * *")]TimerInfo myTimer, TraceWriter log)
|
|
||||||
{
|
|
||||||
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
namespace Bit.Function.Models
|
|
||||||
{
|
|
||||||
public class AccessRuleResponse
|
|
||||||
{
|
|
||||||
public bool Success { get; set; }
|
|
||||||
public AccessRuleResultResponse Result { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace Bit.Function.Models
|
|
||||||
{
|
|
||||||
public class AccessRuleResultResponse
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string Notes { get; set; }
|
|
||||||
public ConfigurationResponse Configuration { get; set; }
|
|
||||||
|
|
||||||
public class ConfigurationResponse
|
|
||||||
{
|
|
||||||
public string Target { get; set; }
|
|
||||||
public string Value { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Bit.Function.Models
|
|
||||||
{
|
|
||||||
public class ListResult
|
|
||||||
{
|
|
||||||
public bool Success { get; set; }
|
|
||||||
public List<AccessRuleResultResponse> Result { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Mail;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Azure.WebJobs;
|
|
||||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
|
||||||
using Microsoft.Azure.WebJobs.Host;
|
|
||||||
|
|
||||||
namespace Bit.Function
|
|
||||||
{
|
|
||||||
public static class NewHelpdeskTicket
|
|
||||||
{
|
|
||||||
[FunctionName("NewHelpdeskTicket")]
|
|
||||||
public static HttpResponseMessage Run(
|
|
||||||
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "api/newhelpdeskticket")]HttpRequestMessage req,
|
|
||||||
TraceWriter log)
|
|
||||||
{
|
|
||||||
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
|
|
||||||
// SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
|
|
||||||
|
|
||||||
var data = req.Content.ReadAsFormDataAsync().Result;
|
|
||||||
if(data == null)
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "No data provided.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(data["name"]))
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "Name is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data["name"].Length > 50)
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "Name must be less than 50 characters.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(data["email"]))
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "Email is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data["email"].Length > 50)
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "Email must be less than 50 characters.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!data["email"].Contains("@") || !data["email"].Contains("."))
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "Email is not valid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(data["message"]))
|
|
||||||
{
|
|
||||||
return req.CreateResponse(HttpStatusCode.BadRequest, "Message is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(!await SubmitApiAsync(data["name"], data["email"], data["message"], log))
|
|
||||||
//{
|
|
||||||
// return req.CreateResponse(HttpStatusCode.BadRequest, "Ticket failed to create.");
|
|
||||||
//}
|
|
||||||
|
|
||||||
SubmitEmail(data["name"], data["email"], data["message"], log);
|
|
||||||
|
|
||||||
return req.CreateResponse(HttpStatusCode.OK, "Ticket created.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async static Task<bool> SubmitApiAsync(string name, string email, string message, TraceWriter log)
|
|
||||||
{
|
|
||||||
using(var client = new HttpClient())
|
|
||||||
{
|
|
||||||
client.BaseAddress = new Uri("https://bitwarden.freshdesk.com/api/v2");
|
|
||||||
client.DefaultRequestHeaders.Accept.Clear();
|
|
||||||
client.DefaultRequestHeaders.Add("Authorization", MakeFreshdeskApiAuthHeader(log));
|
|
||||||
|
|
||||||
var response = await client.PostAsJsonAsync("tickets",
|
|
||||||
new
|
|
||||||
{
|
|
||||||
name = name,
|
|
||||||
email = email,
|
|
||||||
status = 2,
|
|
||||||
priority = 2,
|
|
||||||
source = 1,
|
|
||||||
subject = "Bitwarden.com Website Contact",
|
|
||||||
description = FormatMessage(message)
|
|
||||||
});
|
|
||||||
|
|
||||||
return response.IsSuccessStatusCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SubmitEmail(string name, string email, string message, TraceWriter log)
|
|
||||||
{
|
|
||||||
var sendgridApiKey = ConfigurationManager.AppSettings["SendgridApiKey"];
|
|
||||||
var client = new SmtpClient("smtp.sendgrid.net", /*465*/ 587)
|
|
||||||
{
|
|
||||||
//EnableSsl = true,
|
|
||||||
Credentials = new NetworkCredential("apikey", sendgridApiKey)
|
|
||||||
};
|
|
||||||
|
|
||||||
var fromAddress = new MailAddress(email, name, Encoding.UTF8);
|
|
||||||
var mailMessage = new MailMessage(fromAddress, new MailAddress("bitwardencomsupport@bitwarden.freshdesk.com"))
|
|
||||||
{
|
|
||||||
Subject = "Bitwarden.com Website Contact",
|
|
||||||
Body = FormatMessage(message),
|
|
||||||
IsBodyHtml = true
|
|
||||||
};
|
|
||||||
|
|
||||||
client.SendCompleted += (s, e) =>
|
|
||||||
{
|
|
||||||
client.Dispose();
|
|
||||||
mailMessage.Dispose();
|
|
||||||
};
|
|
||||||
client.SendAsync(mailMessage, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatMessage(string message)
|
|
||||||
{
|
|
||||||
return message.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", "<br>");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string MakeFreshdeskApiAuthHeader(TraceWriter log)
|
|
||||||
{
|
|
||||||
var freshdeskApiKey = ConfigurationManager.AppSettings["FreshdeskApiKey"];
|
|
||||||
var b64Creds = Convert.ToBase64String(
|
|
||||||
Encoding.GetEncoding("ISO-8859-1").GetBytes(freshdeskApiKey + ":X"));
|
|
||||||
return b64Creds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Bit.Function.Models;
|
|
||||||
using Microsoft.Azure.WebJobs;
|
|
||||||
using Microsoft.Azure.WebJobs.Host;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Function
|
|
||||||
{
|
|
||||||
public static class UnblockIp
|
|
||||||
{
|
|
||||||
[FunctionName("UnblockIp")]
|
|
||||||
public static void Run(
|
|
||||||
[QueueTrigger("unblockip", Connection = "")]string myQueueItem,
|
|
||||||
TraceWriter log)
|
|
||||||
{
|
|
||||||
log.Info($"C# Queue trigger function processed: {myQueueItem}");
|
|
||||||
UnblockIpAsync(myQueueItem, log).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task UnblockIpAsync(string id, TraceWriter log)
|
|
||||||
{
|
|
||||||
if(id == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zoneId = ConfigurationManager.AppSettings["ZoneId"];
|
|
||||||
var xAuthEmail = ConfigurationManager.AppSettings["X-Auth-Email"];
|
|
||||||
var xAuthKey = ConfigurationManager.AppSettings["X-Auth-Key"];
|
|
||||||
|
|
||||||
if(id.Contains(".") || id.Contains(":"))
|
|
||||||
{
|
|
||||||
// IP address messages.
|
|
||||||
using(var client = new HttpClient())
|
|
||||||
{
|
|
||||||
client.BaseAddress = new Uri("https://api.cloudflare.com");
|
|
||||||
client.DefaultRequestHeaders.Accept.Clear();
|
|
||||||
client.DefaultRequestHeaders.Add("X-Auth-Email", xAuthEmail);
|
|
||||||
client.DefaultRequestHeaders.Add("X-Auth-Key", xAuthKey);
|
|
||||||
|
|
||||||
var response = await client.GetAsync($"/client/v4/zones/{zoneId}/firewall/access_rules/rules?" +
|
|
||||||
$"configuration_target=ip&configuration_value={id}");
|
|
||||||
|
|
||||||
var responseString = await response.Content.ReadAsStringAsync();
|
|
||||||
var responseJson = JsonConvert.DeserializeObject<ListResult>(responseString);
|
|
||||||
|
|
||||||
if(!responseJson.Success)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(var rule in responseJson.Result)
|
|
||||||
{
|
|
||||||
if(rule.Configuration?.Value != id)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info($"Unblock IP {id}, {rule.Id}");
|
|
||||||
await DeleteRuleAsync(zoneId, xAuthEmail, xAuthKey, rule.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log.Info($"Unblock Id {id}");
|
|
||||||
await DeleteRuleAsync(zoneId, xAuthEmail, xAuthKey, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task DeleteRuleAsync(string zoneId, string xAuthEmail, string xAuthKey, string id)
|
|
||||||
{
|
|
||||||
var path = $"/client/v4/zones/{zoneId}/firewall/access_rules/rules/{id}";
|
|
||||||
using(var client = new HttpClient())
|
|
||||||
{
|
|
||||||
client.BaseAddress = new Uri("https://api.cloudflare.com");
|
|
||||||
client.DefaultRequestHeaders.Accept.Clear();
|
|
||||||
client.DefaultRequestHeaders.Add("X-Auth-Email", xAuthEmail);
|
|
||||||
client.DefaultRequestHeaders.Add("X-Auth-Key", xAuthKey);
|
|
||||||
await client.DeleteAsync(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
{
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"IsEncrypted": false,
|
|
||||||
"Values": {
|
|
||||||
"AzureWebJobsStorage": "SECRET",
|
|
||||||
"AzureWebJobsDashboard": "SECRET"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
|
||||||
<RootNamespace>Bit.Mail</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="wwwroot\**\*">
|
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,17 +0,0 @@
|
|||||||
using Microsoft.AspNetCore;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
|
|
||||||
namespace Bit.Mail
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
WebHost
|
|
||||||
.CreateDefaultBuilder(args)
|
|
||||||
.UseStartup<Startup>()
|
|
||||||
.Build()
|
|
||||||
.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:33104/",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Mail": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "http://localhost:5004",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Bit.Mail
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
public void ConfigureServices(IServiceCollection services) { }
|
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
app.UseFileServer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/// <binding BeforeBuild='build, dist' Clean='clean' ProjectOpened='build. dist' />
|
|
||||||
|
|
||||||
var gulp = require('gulp'),
|
|
||||||
rimraf = require('rimraf'),
|
|
||||||
premailer = require('gulp-premailer');
|
|
||||||
|
|
||||||
var paths = {
|
|
||||||
dist: '../../mail_dist/',
|
|
||||||
wwwroot: './wwwroot/'
|
|
||||||
};
|
|
||||||
|
|
||||||
gulp.task('inline', ['clean'], function () {
|
|
||||||
return gulp.src(paths.wwwroot + 'templates/*.html')
|
|
||||||
.pipe(premailer())
|
|
||||||
.pipe(gulp.dest(paths.dist));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('clean', function (cb) {
|
|
||||||
return rimraf(paths.dist, cb);
|
|
||||||
});
|
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "bitwarden",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"devDependencies": {
|
|
||||||
"gulp": "3.9.1",
|
|
||||||
"rimraf": "2.5.4",
|
|
||||||
"gulp-premailer": "0.4.0"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<!--
|
|
||||||
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
|
|
||||||
-->
|
|
||||||
<system.webServer>
|
|
||||||
<handlers>
|
|
||||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
|
||||||
</handlers>
|
|
||||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00" />
|
|
||||||
</system.webServer>
|
|
||||||
<appSettings>
|
|
||||||
<add key="vs:EnableBrowserLink" value="true" />
|
|
||||||
</appSettings>
|
|
||||||
<system.web>
|
|
||||||
<compilation debug="true"></compilation>
|
|
||||||
</system.web>
|
|
||||||
</configuration>
|
|
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>Bitwarden Mail Templates</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<ol>
|
|
||||||
<li><a href="templates/welcome.html">Welcome</a></li>
|
|
||||||
<li><a href="templates/announcement.html">Announcement</a></li>
|
|
||||||
</ol>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,282 +0,0 @@
|
|||||||
/* -------------------------------------
|
|
||||||
GLOBAL
|
|
||||||
A very basic CSS reset
|
|
||||||
------------------------------------- */
|
|
||||||
body, html, body * {
|
|
||||||
margin: 0;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #333;
|
|
||||||
line-height: 25px;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-webkit-text-size-adjust: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-webkit-text-size-adjust: none;
|
|
||||||
width: 100% !important;
|
|
||||||
height: 100%;
|
|
||||||
line-height: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Let's make sure all tables have defaults */
|
|
||||||
table td {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
table td.middle {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
BODY & CONTAINER
|
|
||||||
------------------------------------- */
|
|
||||||
body {
|
|
||||||
background-color: #f6f6f6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body-wrap {
|
|
||||||
background-color: #f6f6f6;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container, .container-table {
|
|
||||||
width: 600px;
|
|
||||||
max-width: 600px !important;
|
|
||||||
display: block !important;
|
|
||||||
/* makes it centered */
|
|
||||||
clear: both !important;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
|
||||||
display: block;
|
|
||||||
font-size: 0;
|
|
||||||
line-height: 0;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-banner {
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
LOGO, HEADER, FOOTER, MAIN
|
|
||||||
------------------------------------- */
|
|
||||||
.logo {
|
|
||||||
padding: 20px 0 10px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner, .banner img {
|
|
||||||
font-size: 0;
|
|
||||||
line-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
background-color: white;
|
|
||||||
border: 1px solid #e9e9e9;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-banner .main {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrap {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-block {
|
|
||||||
padding: 0 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-block img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-block-spaced {
|
|
||||||
padding: 0 0 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.indented {
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.li {
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
width: 100%;
|
|
||||||
clear: both;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer, .footer p, .footer a, .footer td, .footer br {
|
|
||||||
color: #999;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer .social-icons table {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer .social-icons td {
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
TYPOGRAPHY
|
|
||||||
------------------------------------- */
|
|
||||||
.h3 {
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 25px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.biglink a {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
LINKS & BUTTONS
|
|
||||||
------------------------------------- */
|
|
||||||
a {
|
|
||||||
color: #3c8dbc;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
text-decoration: none;
|
|
||||||
color: white;
|
|
||||||
background-color: #3c8dbc;
|
|
||||||
border: solid #3c8dbc;
|
|
||||||
border-width: 10px 20px;
|
|
||||||
line-height: 2em;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 5px;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
OTHER STYLES THAT MIGHT BE USEFUL
|
|
||||||
------------------------------------- */
|
|
||||||
.last {
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first {
|
|
||||||
margin-top: 0;
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aligncenter {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alignright {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alignleft {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
ALERTS
|
|
||||||
Change the class depending on warning email, good email or bad email
|
|
||||||
------------------------------------- */
|
|
||||||
.alert {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 500;
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 3px 3px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert a {
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert.alert-warning {
|
|
||||||
background-color: #FF9F00;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert.alert-bad {
|
|
||||||
background-color: #D0021B;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert.alert-good {
|
|
||||||
background-color: #68B90F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------
|
|
||||||
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
|
||||||
------------------------------------- */
|
|
||||||
@media only screen and (max-width: 600px) {
|
|
||||||
body {
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container, .container-table {
|
|
||||||
padding: 0 !important;
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding: 0 0 10px 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrap {
|
|
||||||
padding: 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
border-right: none !important;
|
|
||||||
border-left: none !important;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
padding-top: 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
margin-top: 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.indented {
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<title>Announcement</title>
|
|
||||||
<link href="../styles.css" media="all" rel="stylesheet" type="text/css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table class="body-wrap" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td class="container" align="center">
|
|
||||||
<table cellpadding="0" cellspacing="0" class="container-table">
|
|
||||||
<tr>
|
|
||||||
<td class="content content-banner" align="center">
|
|
||||||
<a href="#" title="" target="_blank" class="banner">
|
|
||||||
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Announcement%20Image&w=600&h=158"
|
|
||||||
width="600" alt="" />
|
|
||||||
</a>
|
|
||||||
<table class="main" width="100%" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td class="content-wrap">
|
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td class="h3 content-block">
|
|
||||||
A title!
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
Some text about an announcement.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block indented">
|
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td width="15">•</td>
|
|
||||||
<td class="li">Bullet 1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>•</td>
|
|
||||||
<td class="li">Bullet 2</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block last">
|
|
||||||
Thank you!<br />
|
|
||||||
The Bitwarden Team
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table class="footer" cellpadding="0" cellspacing="0" width="100%">
|
|
||||||
<tr>
|
|
||||||
<td class="aligncenter content-block">
|
|
||||||
8bit Solutions LLC<br />
|
|
||||||
You can <a href="[unsubscribe]">unsubscribe</a> from future mailings.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="aligncenter social-icons" align="center">
|
|
||||||
<table cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td><a href="https://twitter.com/bitwarden_app" target="_blank"><img src="https://bitwarden.com/images/mail-twitter.png" alt="Twitter" width="30" height="30" /></a></td>
|
|
||||||
<td><a href="https://www.facebook.com/bitwarden/" target="_blank"><img src="https://bitwarden.com/images/mail-facebook.png" alt="Facebook" width="30" height="30" /></a></td>
|
|
||||||
<td><a href="https://plus.google.com/+bitwarden" target="_blank"><img src="https://bitwarden.com/images/mail-gplus.png" alt="Google+" width="30" height="30" /></a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,146 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<title>Welcome</title>
|
|
||||||
<link href="../styles.css" media="all" rel="stylesheet" type="text/css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<table class="body-wrap" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td valign="middle" class="aligncenter middle logo">
|
|
||||||
<img src="https://bitwarden.com/images/logo-gray.png" alt="" width="250" height="39" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="container" align="center">
|
|
||||||
<table cellpadding="0" cellspacing="0" class="container-table">
|
|
||||||
<tr>
|
|
||||||
<td class="content" align="center">
|
|
||||||
<table class="main" width="100%" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td class="content-wrap">
|
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
Thank you for creating an account with Bitwarden. You may now log in with your new account.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
Did you know that Bitwarden is free to sync with all of your devices? Download Bitwarden today on:
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="h3">
|
|
||||||
Desktop
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
Access Bitwarden on Windows, macOS, and Linux desktops with our native desktop application.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
<a href="https://bitwarden.com/#download" target="_blank">
|
|
||||||
<img src="https://bitwarden.com/images/mail-os.png" alt="Windows, macOS, and Linux" width="550" height="110" />
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="h3">
|
|
||||||
Web Browser
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
Integrate Bitwarden directly into your favorite browser. Use our browser extensions for a seamless browsing experience.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
<a href="https://bitwarden.com/#download-browser" target="_blank">
|
|
||||||
<img src="https://bitwarden.com/images/mail-browsers.png" alt="Chrome, Firefox, Opera, Edge, Safari, and more" width="550" height="90" />
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="h3">
|
|
||||||
Mobile
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
Take Bitwarden on the go with our mobile apps for your phone or tablet device.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
<a href="https://bitwarden.com/#download-mobile" target="_blank">
|
|
||||||
<img src="https://bitwarden.com/images/mail-stores.png" alt="App Store and Google Play" width="550" height="85" />
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="h3">
|
|
||||||
Web
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Stuck without any of your devices? Using a friend's computer? You can access your Bitwarden vault from any web enabled device by using the web vault.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block h3 biglink">
|
|
||||||
<a target="_blank" href="https://vault.bitwarden.com/?utm_source=welcome_email&utm_medium=email">vault.bitwarden.com</a>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block">
|
|
||||||
If you have any questions or problems you can email us from our website at <a target="_blank" href="https://bitwarden.com/contact/?utm_source=welcome_email&utm_medium=email">https://bitwarden.com/contact</a>.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="content-block last">
|
|
||||||
Thank you!<br />
|
|
||||||
The Bitwarden Team
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table class="footer" cellpadding="0" cellspacing="0" width="100%">
|
|
||||||
<tr>
|
|
||||||
<td class="aligncenter content-block">
|
|
||||||
8bit Solutions LLC
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="aligncenter social-icons" align="center">
|
|
||||||
<table cellpadding="0" cellspacing="0">
|
|
||||||
<tr>
|
|
||||||
<td><a href="https://twitter.com/bitwarden_app" target="_blank"><img src="https://bitwarden.com/images/mail-twitter.png" alt="Twitter" width="30" height="30" /></a></td>
|
|
||||||
<td><a href="https://www.facebook.com/bitwarden/" target="_blank"><img src="https://bitwarden.com/images/mail-facebook.png" alt="Facebook" width="30" height="30" /></a></td>
|
|
||||||
<td><a href="https://plus.google.com/+bitwarden" target="_blank"><img src="https://bitwarden.com/images/mail-gplus.png" alt="Google+" width="30" height="30" /></a></td>
|
|
||||||
<td><a href="https://github.com/bitwarden" target="_blank"><img src="https://bitwarden.com/images/mail-github.png" alt="GitHub" width="30" height="30" /></a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user