mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 10:19:43 +00:00
Align prod schema and deploy tooling
This commit is contained in:
1 parent
d2db86ec7f
commit
7e2e723880
105 files changed
+19014
-131
No files matched your search
@@ -0,0 +1,27 @@
|
||||
# Terraform state files (use remote backend instead)
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
# Exclude all .tfvars files (may contain secrets)
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
|
||||
# Override files
|
||||
override.tf
|
||||
override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
# CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Local .terraform directories
|
||||
.terraform/
|
||||
|
||||
# Lock file should be committed
|
||||
!.terraform.lock.hcl
|
||||
Generated
+25
@@ -0,0 +1,25 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/supabase/supabase" {
|
||||
version = "1.6.1"
|
||||
constraints = "~> 1.0"
|
||||
hashes = [
|
||||
"h1:qQoXMVMdUp4Id9eKYPyTp52t6RchV38rXF10ayMeeNs=",
|
||||
"zh:115437eb15451558b47984155e6e34fb18d85635f7d57a12f5933aa99231ca90",
|
||||
"zh:1403a3be401cc746cbfbaac11f2b5f5f492b4a1142441b380895b20a4ca700f1",
|
||||
"zh:4087e7238f2a1e930f3798c83c5544947f5096803d9132f0694e4036ee6228cc",
|
||||
"zh:4d9effb75c41409700d325fd715d39cb135f958c7442e32d1686f13928e94de7",
|
||||
"zh:575dcc18f686fa3aefd40e5f668e075dc2a4b628804b1f0eba0ba2bad299476d",
|
||||
"zh:5a95fa37e0eb126721c2187dd389f63c09640082cd50cc521a0dfe898eea683c",
|
||||
"zh:6e20a8faa09627a9ef0b7c9950af7da93c69d682fe3bfd930807db0b58aa59a1",
|
||||
"zh:757a8da9f8fafcd2aa9ecb9f4cb2773567090313c736ee95d3fa41bd92535538",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:a815c20e132981abbda986b60445f9786bfd5dd3254bcb52d52e9e31cd105a04",
|
||||
"zh:c665269e5474a7144ec88bb3849dacea2f1c720500e86f84279d4318806044a8",
|
||||
"zh:da054f0bb9bb7432c4f5c66093262566e99403f5e4a5d72853873359472d7c1c",
|
||||
"zh:de584088b3d86ec1889dd719406783f9f3698df0a91007741a156f313bf61aa7",
|
||||
"zh:e83615654ce2c82b1a243c79cc53c29214e7fd81fb286a7e3befb35d5a1c3492",
|
||||
"zh:ed2f7545a8217ab2eae2cf9447c6b7b1ec660764ae764c08b033f5e3800a5608",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
# Terraform Infrastructure
|
||||
|
||||
This directory contains Terraform configuration for managing Supabase project settings as Infrastructure as Code (IaC).
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
terraform/
|
||||
├── modules/
|
||||
│ └── supabase/ # Shared Supabase configuration module
|
||||
│ ├── main.tf # Resource definitions
|
||||
│ ├── variables.tf # Module inputs
|
||||
│ ├── outputs.tf # Module outputs
|
||||
│ └── templates/ # Email templates
|
||||
├── environments/
|
||||
│ ├── prod/ # Production (ckjcrkjpmhqhiucifukx)
|
||||
│ │ ├── main.tf
|
||||
│ │ ├── variables.tf
|
||||
│ │ ├── versions.tf
|
||||
│ │ └── outputs.tf
|
||||
│ └── non-prod/ # Non-production (itbzhrvlgvdmzbnhzhyx)
|
||||
│ ├── main.tf
|
||||
│ ├── variables.tf
|
||||
│ ├── versions.tf
|
||||
│ └── outputs.tf
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## What's Managed
|
||||
|
||||
| Resource | Description |
|
||||
|----------|-------------|
|
||||
| `supabase_settings` | API config, Auth settings, Connection pooler |
|
||||
|
||||
**Not managed by Terraform** (managed via migrations/CLI):
|
||||
- Database schema & migrations
|
||||
- Edge functions
|
||||
- Storage buckets
|
||||
- RLS policies
|
||||
|
||||
## Initial Setup
|
||||
|
||||
### 1. Install Terraform
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
brew install terraform
|
||||
|
||||
# Or download from https://terraform.io/downloads
|
||||
```
|
||||
|
||||
### 2. Get Supabase Access Token
|
||||
|
||||
1. Go to https://supabase.com/dashboard/account/tokens
|
||||
2. Create a new token
|
||||
3. Save it securely
|
||||
|
||||
### 3. Initialize an Environment
|
||||
|
||||
```bash
|
||||
cd terraform/environments/non-prod # or prod
|
||||
export TF_VAR_supabase_access_token=sbp_xxxxx
|
||||
terraform init
|
||||
```
|
||||
|
||||
### 4. Import Existing Settings
|
||||
|
||||
For each environment, import the existing Supabase settings:
|
||||
|
||||
```bash
|
||||
# Non-prod
|
||||
cd terraform/environments/non-prod
|
||||
terraform import module.supabase.supabase_settings.main itbzhrvlgvdmzbnhzhyx
|
||||
|
||||
# Prod
|
||||
cd terraform/environments/prod
|
||||
terraform import module.supabase.supabase_settings.main ckjcrkjpmhqhiucifukx
|
||||
```
|
||||
|
||||
### 5. Verify Configuration
|
||||
|
||||
```bash
|
||||
terraform plan
|
||||
```
|
||||
|
||||
If the plan shows changes, update the module to match the current settings, then re-run plan until it shows no changes.
|
||||
|
||||
## Workflow: Making Changes
|
||||
|
||||
**Always test in non-prod first, then promote to prod.**
|
||||
|
||||
### 1. Make Changes to the Module
|
||||
|
||||
Edit files in `terraform/modules/supabase/` to change shared configuration.
|
||||
|
||||
### 2. Apply to Non-Prod
|
||||
|
||||
```bash
|
||||
cd terraform/environments/non-prod
|
||||
export TF_VAR_supabase_access_token=sbp_xxxxx
|
||||
terraform plan # Review changes
|
||||
terraform apply # Apply changes
|
||||
```
|
||||
|
||||
### 3. Verify in Non-Prod
|
||||
|
||||
Test the changes in the non-prod environment.
|
||||
|
||||
### 4. Apply to Prod
|
||||
|
||||
```bash
|
||||
cd terraform/environments/prod
|
||||
export TF_VAR_supabase_access_token=sbp_xxxxx
|
||||
terraform plan # Review changes
|
||||
terraform apply # Apply changes
|
||||
```
|
||||
|
||||
### 5. Commit Changes
|
||||
|
||||
```bash
|
||||
git add terraform/
|
||||
git commit -m "Update Supabase settings: <description>"
|
||||
git push
|
||||
```
|
||||
|
||||
## Environment-Specific Settings
|
||||
|
||||
Some settings differ between environments. These are controlled by the `is_production` variable in the module:
|
||||
|
||||
| Setting | Production | Non-Prod |
|
||||
|---------|-----------|----------|
|
||||
| SMTP | Resend (custom) | Default |
|
||||
| Email rate limit | 25/hour | 3/hour |
|
||||
|
||||
## CI/CD
|
||||
|
||||
The GitHub Action (`.github/workflows/deploy-supabase.yml`) can be configured to:
|
||||
- Run `terraform plan` on PRs
|
||||
- Run `terraform apply` on merge to master
|
||||
|
||||
Required secret: `SUPABASE_ACCESS_TOKEN`
|
||||
|
||||
Update the workflow to use the new directory structure:
|
||||
|
||||
```yaml
|
||||
- name: Apply to Non-Prod
|
||||
working-directory: terraform/environments/non-prod
|
||||
run: terraform apply -auto-approve
|
||||
|
||||
- name: Apply to Prod
|
||||
working-directory: terraform/environments/prod
|
||||
run: terraform apply -auto-approve
|
||||
```
|
||||
|
||||
## Remote State (Recommended)
|
||||
|
||||
For team environments, configure a remote backend in each environment's `versions.tf`:
|
||||
|
||||
- **Terraform Cloud** (free for small teams)
|
||||
- **S3 backend** (if you have AWS)
|
||||
|
||||
## Secrets
|
||||
|
||||
**Never commit secrets to git!**
|
||||
|
||||
- Use environment variables: `export TF_VAR_supabase_access_token=...`
|
||||
- Use GitHub Secrets for CI/CD
|
||||
- OAuth provider credentials are set in Supabase Dashboard, not Terraform
|
||||
|
||||
## Migration from Workspace-Based Setup
|
||||
|
||||
If you previously used Terraform workspaces, migrate as follows:
|
||||
|
||||
1. Export state from old setup:
|
||||
```bash
|
||||
cd terraform # old location
|
||||
terraform workspace select production
|
||||
terraform state pull > prod.tfstate
|
||||
terraform workspace select non-production
|
||||
terraform state pull > non-prod.tfstate
|
||||
```
|
||||
|
||||
2. Import state to new environments:
|
||||
```bash
|
||||
cd environments/prod
|
||||
terraform init
|
||||
terraform state push ../../prod.tfstate
|
||||
|
||||
cd ../non-prod
|
||||
terraform init
|
||||
terraform state push ../../non-prod.tfstate
|
||||
```
|
||||
|
||||
3. Verify with `terraform plan` in each environment
|
||||
4. Delete old workspace-based files from terraform root
|
||||
@@ -0,0 +1,27 @@
|
||||
# Local .terraform directories
|
||||
.terraform/
|
||||
|
||||
# Terraform state files
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
# Exclude override files as they are usually used to override resources locally
|
||||
override.tf
|
||||
override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
# Ignore CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Sensitive variable files
|
||||
*.tfvars
|
||||
!terraform.tfvars.example
|
||||
|
||||
# Provider lock files (comment out if you want to track)
|
||||
# .terraform.lock.hcl
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/supabase/supabase" {
|
||||
version = "1.6.1"
|
||||
constraints = "~> 1.0"
|
||||
hashes = [
|
||||
"h1:qQoXMVMdUp4Id9eKYPyTp52t6RchV38rXF10ayMeeNs=",
|
||||
"zh:115437eb15451558b47984155e6e34fb18d85635f7d57a12f5933aa99231ca90",
|
||||
"zh:1403a3be401cc746cbfbaac11f2b5f5f492b4a1142441b380895b20a4ca700f1",
|
||||
"zh:4087e7238f2a1e930f3798c83c5544947f5096803d9132f0694e4036ee6228cc",
|
||||
"zh:4d9effb75c41409700d325fd715d39cb135f958c7442e32d1686f13928e94de7",
|
||||
"zh:575dcc18f686fa3aefd40e5f668e075dc2a4b628804b1f0eba0ba2bad299476d",
|
||||
"zh:5a95fa37e0eb126721c2187dd389f63c09640082cd50cc521a0dfe898eea683c",
|
||||
"zh:6e20a8faa09627a9ef0b7c9950af7da93c69d682fe3bfd930807db0b58aa59a1",
|
||||
"zh:757a8da9f8fafcd2aa9ecb9f4cb2773567090313c736ee95d3fa41bd92535538",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:a815c20e132981abbda986b60445f9786bfd5dd3254bcb52d52e9e31cd105a04",
|
||||
"zh:c665269e5474a7144ec88bb3849dacea2f1c720500e86f84279d4318806044a8",
|
||||
"zh:da054f0bb9bb7432c4f5c66093262566e99403f5e4a5d72853873359472d7c1c",
|
||||
"zh:de584088b3d86ec1889dd719406783f9f3698df0a91007741a156f313bf61aa7",
|
||||
"zh:e83615654ce2c82b1a243c79cc53c29214e7fd81fb286a7e3befb35d5a1c3492",
|
||||
"zh:ed2f7545a8217ab2eae2cf9447c6b7b1ec660764ae764c08b033f5e3800a5608",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Non-Production Environment (Staging/Development)
|
||||
#
|
||||
# Supabase project: itbzhrvlgvdmzbnhzhyx
|
||||
# URL: https://itbzhrvlgvdmzbnhzhyx.supabase.co
|
||||
#
|
||||
# Use this environment to test Terraform changes before applying to production.
|
||||
|
||||
module "supabase" {
|
||||
source = "../../modules/supabase"
|
||||
|
||||
project_ref = "itbzhrvlgvdmzbnhzhyx"
|
||||
is_production = false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
output "environment" {
|
||||
description = "Environment name"
|
||||
value = "non-production"
|
||||
}
|
||||
|
||||
output "project_ref" {
|
||||
description = "Supabase project reference"
|
||||
value = module.supabase.project_ref
|
||||
}
|
||||
|
||||
output "project_url" {
|
||||
description = "Supabase project URL"
|
||||
value = module.supabase.project_url
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
variable "supabase_access_token" {
|
||||
description = "Supabase API access token"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
|
||||
required_providers {
|
||||
supabase = {
|
||||
source = "supabase/supabase"
|
||||
version = "~> 1.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Store state remotely (recommended for team environments)
|
||||
# Uncomment and configure one of these backends:
|
||||
|
||||
# Option 1: Terraform Cloud
|
||||
# cloud {
|
||||
# organization = "your-org"
|
||||
# workspaces {
|
||||
# name = "sauci-non-prod"
|
||||
# }
|
||||
# }
|
||||
|
||||
# Option 2: S3 backend
|
||||
# backend "s3" {
|
||||
# bucket = "your-terraform-state-bucket"
|
||||
# key = "sauci/non-prod/terraform.tfstate"
|
||||
# region = "us-east-1"
|
||||
# }
|
||||
}
|
||||
|
||||
provider "supabase" {
|
||||
access_token = var.supabase_access_token
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
# Local .terraform directories
|
||||
.terraform/
|
||||
|
||||
# Terraform state files
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
# Exclude override files as they are usually used to override resources locally
|
||||
override.tf
|
||||
override.tf.json
|
||||
*_override.tf
|
||||
*_override.tf.json
|
||||
|
||||
# Ignore CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Sensitive variable files
|
||||
*.tfvars
|
||||
!terraform.tfvars.example
|
||||
|
||||
# Provider lock files (comment out if you want to track)
|
||||
# .terraform.lock.hcl
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/supabase/supabase" {
|
||||
version = "1.6.1"
|
||||
constraints = "~> 1.0"
|
||||
hashes = [
|
||||
"h1:qQoXMVMdUp4Id9eKYPyTp52t6RchV38rXF10ayMeeNs=",
|
||||
"zh:115437eb15451558b47984155e6e34fb18d85635f7d57a12f5933aa99231ca90",
|
||||
"zh:1403a3be401cc746cbfbaac11f2b5f5f492b4a1142441b380895b20a4ca700f1",
|
||||
"zh:4087e7238f2a1e930f3798c83c5544947f5096803d9132f0694e4036ee6228cc",
|
||||
"zh:4d9effb75c41409700d325fd715d39cb135f958c7442e32d1686f13928e94de7",
|
||||
"zh:575dcc18f686fa3aefd40e5f668e075dc2a4b628804b1f0eba0ba2bad299476d",
|
||||
"zh:5a95fa37e0eb126721c2187dd389f63c09640082cd50cc521a0dfe898eea683c",
|
||||
"zh:6e20a8faa09627a9ef0b7c9950af7da93c69d682fe3bfd930807db0b58aa59a1",
|
||||
"zh:757a8da9f8fafcd2aa9ecb9f4cb2773567090313c736ee95d3fa41bd92535538",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:a815c20e132981abbda986b60445f9786bfd5dd3254bcb52d52e9e31cd105a04",
|
||||
"zh:c665269e5474a7144ec88bb3849dacea2f1c720500e86f84279d4318806044a8",
|
||||
"zh:da054f0bb9bb7432c4f5c66093262566e99403f5e4a5d72853873359472d7c1c",
|
||||
"zh:de584088b3d86ec1889dd719406783f9f3698df0a91007741a156f313bf61aa7",
|
||||
"zh:e83615654ce2c82b1a243c79cc53c29214e7fd81fb286a7e3befb35d5a1c3492",
|
||||
"zh:ed2f7545a8217ab2eae2cf9447c6b7b1ec660764ae764c08b033f5e3800a5608",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# Production Environment
|
||||
#
|
||||
# Supabase project: ckjcrkjpmhqhiucifukx
|
||||
# URL: https://ckjcrkjpmhqhiucifukx.supabase.co
|
||||
|
||||
module "supabase" {
|
||||
source = "../../modules/supabase"
|
||||
|
||||
project_ref = "ckjcrkjpmhqhiucifukx"
|
||||
is_production = true
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
output "environment" {
|
||||
description = "Environment name"
|
||||
value = "production"
|
||||
}
|
||||
|
||||
output "project_ref" {
|
||||
description = "Supabase project reference"
|
||||
value = module.supabase.project_ref
|
||||
}
|
||||
|
||||
output "project_url" {
|
||||
description = "Supabase project URL"
|
||||
value = module.supabase.project_url
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
variable "supabase_access_token" {
|
||||
description = "Supabase API access token"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
|
||||
required_providers {
|
||||
supabase = {
|
||||
source = "supabase/supabase"
|
||||
version = "~> 1.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Store state remotely (recommended for team environments)
|
||||
# Uncomment and configure one of these backends:
|
||||
|
||||
# Option 1: Terraform Cloud
|
||||
# cloud {
|
||||
# organization = "your-org"
|
||||
# workspaces {
|
||||
# name = "sauci-prod"
|
||||
# }
|
||||
# }
|
||||
|
||||
# Option 2: S3 backend
|
||||
# backend "s3" {
|
||||
# bucket = "your-terraform-state-bucket"
|
||||
# key = "sauci/prod/terraform.tfstate"
|
||||
# region = "us-east-1"
|
||||
# }
|
||||
}
|
||||
|
||||
provider "supabase" {
|
||||
access_token = var.supabase_access_token
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
# Supabase Project Configuration
|
||||
#
|
||||
# This manages the configuration for Sauci Supabase projects.
|
||||
# Uses Terraform workspaces to manage multiple environments:
|
||||
# - production: ckjcrkjpmhqhiucifukx
|
||||
# - non-production: itbzhrvlgvdmzbnhzhyx
|
||||
#
|
||||
# Usage:
|
||||
# terraform workspace select production
|
||||
# terraform plan
|
||||
#
|
||||
# To import settings for a new workspace:
|
||||
# terraform workspace new <name>
|
||||
# terraform import supabase_settings.main <project_ref>
|
||||
|
||||
# Project settings - API, Auth, Network, Storage configuration
|
||||
resource "supabase_settings" "main" {
|
||||
project_ref = local.project_ref
|
||||
|
||||
# API Settings
|
||||
api = jsonencode({
|
||||
db_schema = "public,graphql_public"
|
||||
db_extra_search_path = "public, extensions"
|
||||
max_rows = 1000
|
||||
})
|
||||
|
||||
# Auth Settings
|
||||
auth = jsonencode({
|
||||
# Site URL and redirects
|
||||
site_url = "https://sauci.app"
|
||||
uri_allow_list = "app.sauci://**,app.sauci://(auth)/login"
|
||||
|
||||
# Signup and auth settings
|
||||
disable_signup = false
|
||||
external_anonymous_users_enabled = true
|
||||
external_email_enabled = true
|
||||
external_phone_enabled = false
|
||||
|
||||
# OAuth providers
|
||||
external_google_enabled = true
|
||||
external_google_client_id = "764866133492-57iilbc72t1urtmurgioci9tne5l6j67.apps.googleusercontent.com,764866133492-4g566mrb8tm5uti4ejub6oogcvnln7kc.apps.googleusercontent.com,764866133492-e78o2rh3rdjc4rfj2j6r2j77b065kggm.apps.googleusercontent.com"
|
||||
external_google_email_optional = false
|
||||
external_google_skip_nonce_check = false
|
||||
|
||||
external_apple_enabled = true
|
||||
external_apple_client_id = "com.sauci.app"
|
||||
external_apple_email_optional = false
|
||||
|
||||
# Disabled OAuth providers (with email_optional settings)
|
||||
external_azure_enabled = false
|
||||
external_azure_email_optional = false
|
||||
external_bitbucket_enabled = false
|
||||
external_bitbucket_email_optional = false
|
||||
external_discord_enabled = false
|
||||
external_discord_email_optional = false
|
||||
external_facebook_enabled = false
|
||||
external_facebook_email_optional = false
|
||||
external_figma_enabled = false
|
||||
external_figma_email_optional = false
|
||||
external_github_enabled = false
|
||||
external_github_email_optional = false
|
||||
external_gitlab_enabled = false
|
||||
external_gitlab_email_optional = false
|
||||
external_kakao_enabled = false
|
||||
external_kakao_email_optional = false
|
||||
external_keycloak_enabled = false
|
||||
external_keycloak_email_optional = false
|
||||
external_linkedin_oidc_enabled = false
|
||||
external_linkedin_oidc_email_optional = false
|
||||
external_notion_enabled = false
|
||||
external_notion_email_optional = false
|
||||
external_slack_enabled = false
|
||||
external_slack_email_optional = false
|
||||
external_slack_oidc_enabled = false
|
||||
external_slack_oidc_email_optional = false
|
||||
external_spotify_enabled = false
|
||||
external_spotify_email_optional = false
|
||||
external_twitch_enabled = false
|
||||
external_twitch_email_optional = false
|
||||
external_twitter_enabled = false
|
||||
external_twitter_email_optional = false
|
||||
external_workos_enabled = false
|
||||
external_zoom_enabled = false
|
||||
external_zoom_email_optional = false
|
||||
external_web3_ethereum_enabled = false
|
||||
external_web3_solana_enabled = false
|
||||
|
||||
# JWT settings
|
||||
jwt_exp = 3600
|
||||
refresh_token_rotation_enabled = true
|
||||
security_refresh_token_reuse_interval = 10
|
||||
|
||||
# Session settings
|
||||
sessions_inactivity_timeout = 0
|
||||
sessions_single_per_user = false
|
||||
sessions_timebox = 0
|
||||
|
||||
# API settings
|
||||
api_max_request_duration = 10
|
||||
db_max_pool_size = 10
|
||||
db_max_pool_size_unit = "connections"
|
||||
|
||||
# Password settings
|
||||
password_min_length = 6
|
||||
password_hibp_enabled = false
|
||||
|
||||
# Rate limits (rate_limit_email_sent requires custom SMTP in production)
|
||||
rate_limit_anonymous_users = 30
|
||||
rate_limit_email_sent = local.is_production ? 25 : 3
|
||||
rate_limit_otp = 30
|
||||
rate_limit_sms_sent = 30
|
||||
rate_limit_token_refresh = 150
|
||||
rate_limit_verify = 30
|
||||
rate_limit_web3 = 30
|
||||
|
||||
# MFA settings
|
||||
mfa_max_enrolled_factors = 10
|
||||
mfa_totp_enroll_enabled = true
|
||||
mfa_totp_verify_enabled = true
|
||||
mfa_phone_enroll_enabled = false
|
||||
mfa_phone_verify_enabled = false
|
||||
mfa_phone_max_frequency = 5
|
||||
mfa_phone_otp_length = 6
|
||||
mfa_phone_template = "Your code is {{ .Code }}"
|
||||
mfa_web_authn_enroll_enabled = false
|
||||
mfa_web_authn_verify_enabled = false
|
||||
|
||||
# SAML
|
||||
saml_enabled = false
|
||||
|
||||
# Security settings
|
||||
security_captcha_enabled = false
|
||||
security_captcha_provider = "hcaptcha"
|
||||
security_manual_linking_enabled = true
|
||||
security_update_password_require_reauthentication = false
|
||||
|
||||
# Email/mailer settings
|
||||
mailer_autoconfirm = false
|
||||
mailer_allow_unverified_email_sign_ins = false
|
||||
mailer_secure_email_change_enabled = true
|
||||
mailer_otp_exp = 3600
|
||||
mailer_otp_length = 8
|
||||
|
||||
# Mailer notifications
|
||||
mailer_notifications_email_changed_enabled = false
|
||||
mailer_notifications_identity_linked_enabled = false
|
||||
mailer_notifications_identity_unlinked_enabled = false
|
||||
mailer_notifications_mfa_factor_enrolled_enabled = false
|
||||
mailer_notifications_mfa_factor_unenrolled_enabled = false
|
||||
mailer_notifications_password_changed_enabled = false
|
||||
mailer_notifications_phone_changed_enabled = false
|
||||
|
||||
# Email subjects
|
||||
mailer_subjects_confirmation = "Confirm Your Signup"
|
||||
mailer_subjects_email_change = "sauci@jbrunton.co.uk"
|
||||
mailer_subjects_email_changed_notification = "Your email address has been changed"
|
||||
mailer_subjects_identity_linked_notification = "A new identity has been linked"
|
||||
mailer_subjects_identity_unlinked_notification = "An identity has been unlinked"
|
||||
mailer_subjects_invite = "You have been invited"
|
||||
mailer_subjects_magic_link = "Your Magic Link"
|
||||
mailer_subjects_mfa_factor_enrolled_notification = "A new MFA factor has been enrolled"
|
||||
mailer_subjects_mfa_factor_unenrolled_notification = "An MFA factor has been unenrolled"
|
||||
mailer_subjects_password_changed_notification = "Your password has been changed"
|
||||
mailer_subjects_phone_changed_notification = "Your phone number has been changed"
|
||||
mailer_subjects_reauthentication = "Confirm Reauthentication"
|
||||
mailer_subjects_recovery = "Reset Your Password"
|
||||
|
||||
# Email templates (see templates/ directory for full HTML)
|
||||
mailer_templates_confirmation_content = file("${path.module}/templates/confirmation.html")
|
||||
mailer_templates_email_change_content = file("${path.module}/templates/email_change.html")
|
||||
mailer_templates_invite_content = file("${path.module}/templates/invite.html")
|
||||
mailer_templates_magic_link_content = file("${path.module}/templates/magic_link.html")
|
||||
mailer_templates_recovery_content = file("${path.module}/templates/recovery.html")
|
||||
mailer_templates_reauthentication_content = "Enter the code: {{ .Token }}"
|
||||
|
||||
# Notification templates (simple HTML)
|
||||
mailer_templates_email_changed_notification_content = <<-EOT
|
||||
<h2>Your email address has been changed</h2>
|
||||
<p>The email address for your account has been changed from {{ .OldEmail }} to {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support.</p>
|
||||
EOT
|
||||
mailer_templates_identity_linked_notification_content = <<-EOT
|
||||
<h2>A new identity has been linked</h2>
|
||||
<p>A new identity ({{ .Provider }}) has been linked to your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_identity_unlinked_notification_content = <<-EOT
|
||||
<h2>An identity has been unlinked</h2>
|
||||
<p>An identity ({{ .Provider }}) has been unlinked from your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_mfa_factor_enrolled_notification_content = <<-EOT
|
||||
<h2>A new MFA factor has been enrolled</h2>
|
||||
<p>A new factor ({{ .FactorType }}) has been enrolled for your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_mfa_factor_unenrolled_notification_content = <<-EOT
|
||||
<h2>An MFA factor has been unenrolled</h2>
|
||||
<p>A factor ({{ .FactorType }}) has been unenrolled for your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_password_changed_notification_content = <<-EOT
|
||||
<h2>Your password has been changed</h2>
|
||||
<p>This is a confirmation that the password for your account {{ .Email }} has just been changed.</p>
|
||||
<p>If you did not make this change, please contact support.</p>
|
||||
EOT
|
||||
mailer_templates_phone_changed_notification_content = <<-EOT
|
||||
<h2>Your phone number has been changed</h2>
|
||||
<p>The phone number for your account {{ .Email }} has been changed from {{ .OldPhone }} to {{ .Phone }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
|
||||
# SMS settings
|
||||
sms_autoconfirm = false
|
||||
sms_max_frequency = 5
|
||||
sms_otp_exp = 60
|
||||
sms_otp_length = 6
|
||||
sms_provider = "twilio"
|
||||
sms_template = "Your code is {{ .Code }}"
|
||||
|
||||
# SMTP settings (only for production - requires custom SMTP configured)
|
||||
smtp_admin_email = local.is_production ? "team@send.sauci.app" : null
|
||||
smtp_host = local.is_production ? "smtp.resend.com" : null
|
||||
smtp_max_frequency = local.is_production ? 1 : null
|
||||
smtp_port = local.is_production ? "465" : null
|
||||
smtp_sender_name = local.is_production ? "Sauci App" : null
|
||||
smtp_user = local.is_production ? "resend" : null
|
||||
|
||||
# Hook settings (only include hooks available on current plan)
|
||||
hook_after_user_created_enabled = false
|
||||
hook_before_user_created_enabled = false
|
||||
hook_custom_access_token_enabled = false
|
||||
hook_send_email_enabled = false
|
||||
hook_send_sms_enabled = false
|
||||
# Note: hook_mfa_verification_attempt and hook_password_verification_attempt
|
||||
# require Team plan or higher - omitted to avoid 402 errors
|
||||
})
|
||||
|
||||
# Database Settings (empty - managed via migrations)
|
||||
database = jsonencode({})
|
||||
|
||||
# Network Settings
|
||||
network = jsonencode({
|
||||
restrictions = ["0.0.0.0/0", "::/0"]
|
||||
})
|
||||
|
||||
# Storage Settings
|
||||
storage = jsonencode({
|
||||
fileSizeLimit = 52428800 # 50MB
|
||||
databasePoolMode = "recycled"
|
||||
migrationVersion = "buckets-objects-grants-postgres"
|
||||
capabilities = {
|
||||
iceberg_catalog = true
|
||||
list_v2 = true
|
||||
}
|
||||
features = {
|
||||
imageTransformation = { enabled = true }
|
||||
s3Protocol = { enabled = true }
|
||||
icebergCatalog = {
|
||||
enabled = true
|
||||
maxCatalogs = 2
|
||||
maxNamespaces = 10
|
||||
maxTables = 10
|
||||
}
|
||||
vectorBuckets = {
|
||||
enabled = false
|
||||
maxBuckets = 10
|
||||
maxIndexes = 5
|
||||
}
|
||||
}
|
||||
external = {
|
||||
upstreamTarget = "canary"
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
# Supabase Project Configuration Module
|
||||
#
|
||||
# This module manages Supabase project settings including API, Auth, Network, and Storage.
|
||||
# Environment-specific settings (SMTP, rate limits) are controlled via input variables.
|
||||
|
||||
resource "supabase_settings" "main" {
|
||||
project_ref = var.project_ref
|
||||
|
||||
# API Settings
|
||||
api = jsonencode({
|
||||
db_schema = "public,graphql_public"
|
||||
db_extra_search_path = "public, extensions"
|
||||
max_rows = 1000
|
||||
})
|
||||
|
||||
# Auth Settings
|
||||
auth = jsonencode({
|
||||
# Site URL and redirects
|
||||
site_url = "https://sauci.app"
|
||||
uri_allow_list = "app.sauci://**,app.sauci://(auth)/login"
|
||||
|
||||
# Signup and auth settings
|
||||
disable_signup = false
|
||||
external_anonymous_users_enabled = true
|
||||
external_email_enabled = true
|
||||
external_phone_enabled = false
|
||||
|
||||
# OAuth providers
|
||||
external_google_enabled = true
|
||||
external_google_client_id = "764866133492-57iilbc72t1urtmurgioci9tne5l6j67.apps.googleusercontent.com,764866133492-4g566mrb8tm5uti4ejub6oogcvnln7kc.apps.googleusercontent.com,764866133492-e78o2rh3rdjc4rfj2j6r2j77b065kggm.apps.googleusercontent.com"
|
||||
external_google_email_optional = false
|
||||
external_google_skip_nonce_check = false
|
||||
|
||||
external_apple_enabled = true
|
||||
external_apple_client_id = "com.sauci.app"
|
||||
external_apple_email_optional = false
|
||||
|
||||
# Disabled OAuth providers (with email_optional settings)
|
||||
external_azure_enabled = false
|
||||
external_azure_email_optional = false
|
||||
external_bitbucket_enabled = false
|
||||
external_bitbucket_email_optional = false
|
||||
external_discord_enabled = false
|
||||
external_discord_email_optional = false
|
||||
external_facebook_enabled = false
|
||||
external_facebook_email_optional = false
|
||||
external_figma_enabled = false
|
||||
external_figma_email_optional = false
|
||||
external_github_enabled = false
|
||||
external_github_email_optional = false
|
||||
external_gitlab_enabled = false
|
||||
external_gitlab_email_optional = false
|
||||
external_kakao_enabled = false
|
||||
external_kakao_email_optional = false
|
||||
external_keycloak_enabled = false
|
||||
external_keycloak_email_optional = false
|
||||
external_linkedin_oidc_enabled = false
|
||||
external_linkedin_oidc_email_optional = false
|
||||
external_notion_enabled = false
|
||||
external_notion_email_optional = false
|
||||
external_slack_enabled = false
|
||||
external_slack_email_optional = false
|
||||
external_slack_oidc_enabled = false
|
||||
external_slack_oidc_email_optional = false
|
||||
external_spotify_enabled = false
|
||||
external_spotify_email_optional = false
|
||||
external_twitch_enabled = false
|
||||
external_twitch_email_optional = false
|
||||
external_twitter_enabled = false
|
||||
external_twitter_email_optional = false
|
||||
external_workos_enabled = false
|
||||
external_zoom_enabled = false
|
||||
external_zoom_email_optional = false
|
||||
external_web3_ethereum_enabled = false
|
||||
external_web3_solana_enabled = false
|
||||
|
||||
# JWT settings
|
||||
jwt_exp = 3600
|
||||
refresh_token_rotation_enabled = true
|
||||
security_refresh_token_reuse_interval = 10
|
||||
|
||||
# Session settings
|
||||
sessions_inactivity_timeout = 0
|
||||
sessions_single_per_user = false
|
||||
sessions_timebox = 0
|
||||
|
||||
# API settings
|
||||
api_max_request_duration = 10
|
||||
db_max_pool_size = 10
|
||||
db_max_pool_size_unit = "connections"
|
||||
|
||||
# Password settings
|
||||
password_min_length = 6
|
||||
password_hibp_enabled = false
|
||||
|
||||
# Rate limits (rate_limit_email_sent requires custom SMTP in production)
|
||||
rate_limit_anonymous_users = 30
|
||||
rate_limit_email_sent = var.is_production ? 25 : 3
|
||||
rate_limit_otp = 30
|
||||
rate_limit_sms_sent = 30
|
||||
rate_limit_token_refresh = 150
|
||||
rate_limit_verify = 30
|
||||
rate_limit_web3 = 30
|
||||
|
||||
# MFA settings
|
||||
mfa_max_enrolled_factors = 10
|
||||
mfa_totp_enroll_enabled = true
|
||||
mfa_totp_verify_enabled = true
|
||||
mfa_phone_enroll_enabled = false
|
||||
mfa_phone_verify_enabled = false
|
||||
mfa_phone_max_frequency = 5
|
||||
mfa_phone_otp_length = 6
|
||||
mfa_phone_template = "Your code is {{ .Code }}"
|
||||
mfa_web_authn_enroll_enabled = false
|
||||
mfa_web_authn_verify_enabled = false
|
||||
|
||||
# SAML
|
||||
saml_enabled = false
|
||||
|
||||
# Security settings
|
||||
security_captcha_enabled = false
|
||||
security_captcha_provider = "hcaptcha"
|
||||
security_manual_linking_enabled = true
|
||||
security_update_password_require_reauthentication = false
|
||||
|
||||
# Email/mailer settings
|
||||
mailer_autoconfirm = false
|
||||
mailer_allow_unverified_email_sign_ins = false
|
||||
mailer_secure_email_change_enabled = true
|
||||
mailer_otp_exp = 3600
|
||||
mailer_otp_length = 8
|
||||
|
||||
# Mailer notifications
|
||||
mailer_notifications_email_changed_enabled = false
|
||||
mailer_notifications_identity_linked_enabled = false
|
||||
mailer_notifications_identity_unlinked_enabled = false
|
||||
mailer_notifications_mfa_factor_enrolled_enabled = false
|
||||
mailer_notifications_mfa_factor_unenrolled_enabled = false
|
||||
mailer_notifications_password_changed_enabled = false
|
||||
mailer_notifications_phone_changed_enabled = false
|
||||
|
||||
# Email subjects
|
||||
mailer_subjects_confirmation = "Confirm Your Signup"
|
||||
mailer_subjects_email_change = "sauci@jbrunton.co.uk"
|
||||
mailer_subjects_email_changed_notification = "Your email address has been changed"
|
||||
mailer_subjects_identity_linked_notification = "A new identity has been linked"
|
||||
mailer_subjects_identity_unlinked_notification = "An identity has been unlinked"
|
||||
mailer_subjects_invite = "You have been invited"
|
||||
mailer_subjects_magic_link = "Your Magic Link"
|
||||
mailer_subjects_mfa_factor_enrolled_notification = "A new MFA factor has been enrolled"
|
||||
mailer_subjects_mfa_factor_unenrolled_notification = "An MFA factor has been unenrolled"
|
||||
mailer_subjects_password_changed_notification = "Your password has been changed"
|
||||
mailer_subjects_phone_changed_notification = "Your phone number has been changed"
|
||||
mailer_subjects_reauthentication = "Confirm Reauthentication"
|
||||
mailer_subjects_recovery = "Reset Your Password"
|
||||
|
||||
# Email templates (loaded from templates directory)
|
||||
mailer_templates_confirmation_content = file("${path.module}/templates/confirmation.html")
|
||||
mailer_templates_email_change_content = file("${path.module}/templates/email_change.html")
|
||||
mailer_templates_invite_content = file("${path.module}/templates/invite.html")
|
||||
mailer_templates_magic_link_content = file("${path.module}/templates/magic_link.html")
|
||||
mailer_templates_recovery_content = file("${path.module}/templates/recovery.html")
|
||||
mailer_templates_reauthentication_content = "Enter the code: {{ .Token }}"
|
||||
|
||||
# Notification templates (simple HTML)
|
||||
mailer_templates_email_changed_notification_content = <<-EOT
|
||||
<h2>Your email address has been changed</h2>
|
||||
<p>The email address for your account has been changed from {{ .OldEmail }} to {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support.</p>
|
||||
EOT
|
||||
mailer_templates_identity_linked_notification_content = <<-EOT
|
||||
<h2>A new identity has been linked</h2>
|
||||
<p>A new identity ({{ .Provider }}) has been linked to your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_identity_unlinked_notification_content = <<-EOT
|
||||
<h2>An identity has been unlinked</h2>
|
||||
<p>An identity ({{ .Provider }}) has been unlinked from your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_mfa_factor_enrolled_notification_content = <<-EOT
|
||||
<h2>A new MFA factor has been enrolled</h2>
|
||||
<p>A new factor ({{ .FactorType }}) has been enrolled for your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_mfa_factor_unenrolled_notification_content = <<-EOT
|
||||
<h2>An MFA factor has been unenrolled</h2>
|
||||
<p>A factor ({{ .FactorType }}) has been unenrolled for your account {{ .Email }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
mailer_templates_password_changed_notification_content = <<-EOT
|
||||
<h2>Your password has been changed</h2>
|
||||
<p>This is a confirmation that the password for your account {{ .Email }} has just been changed.</p>
|
||||
<p>If you did not make this change, please contact support.</p>
|
||||
EOT
|
||||
mailer_templates_phone_changed_notification_content = <<-EOT
|
||||
<h2>Your phone number has been changed</h2>
|
||||
<p>The phone number for your account {{ .Email }} has been changed from {{ .OldPhone }} to {{ .Phone }}.</p>
|
||||
<p>If you did not make this change, please contact support immediately.</p>
|
||||
EOT
|
||||
|
||||
# SMS settings
|
||||
sms_autoconfirm = false
|
||||
sms_max_frequency = 5
|
||||
sms_otp_exp = 60
|
||||
sms_otp_length = 6
|
||||
sms_provider = "twilio"
|
||||
sms_template = "Your code is {{ .Code }}"
|
||||
|
||||
# SMTP settings (only for production - requires custom SMTP configured)
|
||||
smtp_admin_email = var.is_production ? "team@send.sauci.app" : null
|
||||
smtp_host = var.is_production ? "smtp.resend.com" : null
|
||||
smtp_max_frequency = var.is_production ? 1 : null
|
||||
smtp_port = var.is_production ? "465" : null
|
||||
smtp_sender_name = var.is_production ? "Sauci App" : null
|
||||
smtp_user = var.is_production ? "resend" : null
|
||||
|
||||
# Hook settings (only include hooks available on current plan)
|
||||
hook_after_user_created_enabled = false
|
||||
hook_before_user_created_enabled = false
|
||||
hook_custom_access_token_enabled = false
|
||||
hook_send_email_enabled = false
|
||||
hook_send_sms_enabled = false
|
||||
# Note: hook_mfa_verification_attempt and hook_password_verification_attempt
|
||||
# require Team plan or higher - omitted to avoid 402 errors
|
||||
})
|
||||
|
||||
# Database Settings (empty - managed via migrations)
|
||||
database = jsonencode({})
|
||||
|
||||
# Network Settings
|
||||
network = jsonencode({
|
||||
restrictions = ["0.0.0.0/0", "::/0"]
|
||||
})
|
||||
|
||||
# Storage Settings
|
||||
storage = jsonencode({
|
||||
fileSizeLimit = 52428800 # 50MB
|
||||
databasePoolMode = "recycled"
|
||||
migrationVersion = "buckets-objects-grants-postgres"
|
||||
capabilities = {
|
||||
iceberg_catalog = true
|
||||
list_v2 = true
|
||||
}
|
||||
features = {
|
||||
imageTransformation = { enabled = true }
|
||||
s3Protocol = { enabled = true }
|
||||
icebergCatalog = {
|
||||
enabled = true
|
||||
maxCatalogs = 2
|
||||
maxNamespaces = 10
|
||||
maxTables = 10
|
||||
}
|
||||
vectorBuckets = {
|
||||
enabled = false
|
||||
maxBuckets = 10
|
||||
maxIndexes = 5
|
||||
}
|
||||
}
|
||||
external = {
|
||||
upstreamTarget = "canary"
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
output "project_ref" {
|
||||
description = "Supabase project reference"
|
||||
value = var.project_ref
|
||||
}
|
||||
|
||||
output "project_url" {
|
||||
description = "Supabase project URL"
|
||||
value = "https://${var.project_ref}.supabase.co"
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Confirm Your Email - Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#e94560">
|
||||
<tr>
|
||||
<td align="center" style="padding: 16px 40px; background-color: #e94560;">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
💌
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Welcome to Sauci
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
You're one step away from deepening your connection. Confirm your email to start your journey together.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:180px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Confirm Email</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Confirm Email
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center;">
|
||||
This link will expire in 24 hours.
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't create an account, you can safely ignore this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Confirm Email Change - Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
✉
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Confirm Email Change
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
You requested to change your email address. Click the button below to confirm this change.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:200px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Confirm New Email</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Confirm New Email
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Info Notice -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 8px;">
|
||||
<tr>
|
||||
<td style="padding: 16px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #8888aa; text-align: center; line-height: 1.5;">
|
||||
📩 After confirming, you'll use your new email address to sign in to Sauci.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center;">
|
||||
Didn't request this change?
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't request an email change, please secure your account by resetting your password immediately.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,227 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>You're Invited to Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
💕
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
You've Been Invited
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
Someone special has invited you to join Sauci, the app designed to help couples deepen their connection and discover new things about each other.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:200px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Accept Invitation</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Accept Invitation
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Features Section -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#222240" style="background-color: #222240; border-radius: 12px;">
|
||||
<tr>
|
||||
<td style="padding: 20px;">
|
||||
<p style="margin: 0 0 12px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; font-weight: 600; color: #9999aa; text-align: center; text-transform: uppercase; letter-spacing: 1px;">
|
||||
What awaits you
|
||||
</p>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 8px 0;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 14px; color: #8888aa; text-align: center;">
|
||||
🔥 Thoughtful questions to spark conversations
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 14px; color: #8888aa; text-align: center;">
|
||||
💌 Discover mutual interests with your partner
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 14px; color: #8888aa; text-align: center;">
|
||||
💬 Private chats when you both match
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
This invitation link will expire in 7 days. If you didn't expect this invitation, you can safely ignore this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,204 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Sign In to Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
✨
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Your Magic Link
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
Click the button below to securely sign in to your Sauci account. No password needed.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:180px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Sign In to Sauci</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Sign In to Sauci
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Security Notice -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 8px;">
|
||||
<tr>
|
||||
<td style="padding: 16px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #8888aa; text-align: center; line-height: 1.5;">
|
||||
🔒 This link is unique to you and expires in 1 hour for your security.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't request this sign in link, you can safely ignore this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Reset Your Password - Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
🔐
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Reset Your Password
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
We received a request to reset your password. Click the button below to choose a new one.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:180px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Reset Password</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Reset Password
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Security Notice -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 8px;">
|
||||
<tr>
|
||||
<td style="padding: 16px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #8888aa; text-align: center; line-height: 1.5;">
|
||||
⏰ This link expires in 1 hour. After resetting, you'll need to sign in again on all devices.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center;">
|
||||
Didn't request this?
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't request a password reset, you can safely ignore this email. Your password won't change until you click the link above.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
variable "project_ref" {
|
||||
description = "Supabase project reference ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "is_production" {
|
||||
description = "Whether this is the production environment (enables SMTP, higher rate limits)"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
|
||||
required_providers {
|
||||
supabase = {
|
||||
source = "supabase/supabase"
|
||||
version = "~> 1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
output "workspace" {
|
||||
description = "Current Terraform workspace"
|
||||
value = terraform.workspace
|
||||
}
|
||||
|
||||
output "project_ref" {
|
||||
description = "Supabase project reference"
|
||||
value = local.project_ref
|
||||
}
|
||||
|
||||
output "project_url" {
|
||||
description = "Supabase project URL"
|
||||
value = "https://${local.project_ref}.supabase.co"
|
||||
}
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Import existing Supabase production settings into Terraform state
|
||||
# This script helps extract current configuration for IaC management
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. Set SUPABASE_ACCESS_TOKEN environment variable
|
||||
# 2. Run from the terraform directory
|
||||
|
||||
PROJECT_REF="ckjcrkjpmhqhiucifukx"
|
||||
|
||||
echo "=== Supabase Terraform Import Script ==="
|
||||
echo ""
|
||||
|
||||
# Check for access token
|
||||
if [ -z "$SUPABASE_ACCESS_TOKEN" ]; then
|
||||
echo "Error: SUPABASE_ACCESS_TOKEN environment variable is not set"
|
||||
echo ""
|
||||
echo "Get your token from: https://supabase.com/dashboard/account/tokens"
|
||||
echo "Then run: export SUPABASE_ACCESS_TOKEN=sbp_xxxxx"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Export for Terraform
|
||||
export TF_VAR_supabase_access_token="$SUPABASE_ACCESS_TOKEN"
|
||||
|
||||
echo "1. Initializing Terraform..."
|
||||
terraform init
|
||||
|
||||
echo ""
|
||||
echo "2. Importing production settings..."
|
||||
echo " Project: $PROJECT_REF"
|
||||
echo ""
|
||||
|
||||
# Import settings (will fail if already imported, that's OK)
|
||||
terraform import supabase_settings.production "$PROJECT_REF" 2>/dev/null || echo " (Settings may already be imported)"
|
||||
|
||||
echo ""
|
||||
echo "3. Showing current state..."
|
||||
echo ""
|
||||
terraform show
|
||||
|
||||
echo ""
|
||||
echo "=== Import Complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Review the terraform show output above"
|
||||
echo "2. Update main.tf to match your actual production settings"
|
||||
echo "3. Run 'terraform plan' to verify no changes are needed"
|
||||
echo "4. Commit the updated main.tf"
|
||||
@@ -0,0 +1,206 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Confirm Your Email - Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#e94560">
|
||||
<tr>
|
||||
<td align="center" style="padding: 16px 40px; background-color: #e94560;">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
💌
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Welcome to Sauci
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
You're one step away from deepening your connection. Confirm your email to start your journey together.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:180px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Confirm Email</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Confirm Email
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center;">
|
||||
This link will expire in 24 hours.
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't create an account, you can safely ignore this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Confirm Email Change - Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
✉
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Confirm Email Change
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
You requested to change your email address. Click the button below to confirm this change.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:200px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Confirm New Email</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Confirm New Email
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Info Notice -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 8px;">
|
||||
<tr>
|
||||
<td style="padding: 16px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #8888aa; text-align: center; line-height: 1.5;">
|
||||
📩 After confirming, you'll use your new email address to sign in to Sauci.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center;">
|
||||
Didn't request this change?
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't request an email change, please secure your account by resetting your password immediately.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,227 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>You're Invited to Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
💕
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
You've Been Invited
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
Someone special has invited you to join Sauci, the app designed to help couples deepen their connection and discover new things about each other.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:200px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Accept Invitation</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Accept Invitation
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Features Section -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#222240" style="background-color: #222240; border-radius: 12px;">
|
||||
<tr>
|
||||
<td style="padding: 20px;">
|
||||
<p style="margin: 0 0 12px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; font-weight: 600; color: #9999aa; text-align: center; text-transform: uppercase; letter-spacing: 1px;">
|
||||
What awaits you
|
||||
</p>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 8px 0;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 14px; color: #8888aa; text-align: center;">
|
||||
🔥 Thoughtful questions to spark conversations
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 14px; color: #8888aa; text-align: center;">
|
||||
💌 Discover mutual interests with your partner
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 14px; color: #8888aa; text-align: center;">
|
||||
💬 Private chats when you both match
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
This invitation link will expire in 7 days. If you didn't expect this invitation, you can safely ignore this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,204 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Sign In to Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
✨
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Your Magic Link
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
Click the button below to securely sign in to your Sauci account. No password needed.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:180px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Sign In to Sauci</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Sign In to Sauci
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Security Notice -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 8px;">
|
||||
<tr>
|
||||
<td style="padding: 16px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #8888aa; text-align: center; line-height: 1.5;">
|
||||
🔒 This link is unique to you and expires in 1 hour for your security.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't request this sign in link, you can safely ignore this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no,address=no,email=no,date=no,url=no">
|
||||
<title>Reset Your Password - Sauci</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse; }
|
||||
td { font-family: Arial, sans-serif; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<style>
|
||||
body { margin: 0 !important; padding: 0 !important; }
|
||||
table { border-spacing: 0 !important; border-collapse: collapse !important; }
|
||||
td { padding: 0; }
|
||||
img { border: 0; line-height: 100%; outline: none; text-decoration: none; }
|
||||
a { text-decoration: none; }
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-container { width: 100% !important; }
|
||||
.content-padding { padding-left: 20px !important; padding-right: 20px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; word-spacing: normal; background-color: #0d0d1a;">
|
||||
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #0d0d1a;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<![endif]-->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin: 0 auto;" bgcolor="#0d0d1a">
|
||||
<tr>
|
||||
<td align="center" valign="top" bgcolor="#0d0d1a" style="background-color: #0d0d1a;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="520" class="email-container" style="margin: 0 auto;">
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo Section -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 0 20px 24px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#e94560" style="background-color: #e94560; padding: 16px 60px; border-radius: 8px;">
|
||||
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">Sauci</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Card -->
|
||||
<tr>
|
||||
<td class="content-padding" style="padding: 0 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#1a1a2e" style="background-color: #1a1a2e; border-radius: 16px;">
|
||||
|
||||
<!-- Top Accent Bar -->
|
||||
<tr>
|
||||
<td height="4" bgcolor="#e94560" style="background-color: #e94560; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
|
||||
<!-- Card Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;" bgcolor="#1a1a2e">
|
||||
|
||||
<!-- Icon -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="56" height="56" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 28px; font-size: 24px;">
|
||||
🔐
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Heading -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 16px;">
|
||||
<h1 style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 24px; font-weight: 600; color: #ffffff; line-height: 1.3;">
|
||||
Reset Your Password
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Subtext -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; color: #9999aa; text-align: center; line-height: 1.6;">
|
||||
We received a request to reset your password. Click the button below to choose a new one.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 32px;">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="{{ .ConfirmationURL }}" style="height:48px;v-text-anchor:middle;width:180px;" arcsize="25%" strokecolor="#e94560" fillcolor="#e94560">
|
||||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Arial,sans-serif;font-size:15px;font-weight:bold;">Reset Password</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<a href="{{ .ConfirmationURL }}" target="_blank" style="display: inline-block; padding: 14px 40px; background-color: #e94560; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 15px; font-weight: 600; border-radius: 12px; text-decoration: none;">
|
||||
Reset Password
|
||||
</a>
|
||||
<!--<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Security Notice -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#2a2a3e" style="background-color: #2a2a3e; border-radius: 8px;">
|
||||
<tr>
|
||||
<td style="padding: 16px;">
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #8888aa; text-align: center; line-height: 1.5;">
|
||||
⏰ This link expires in 1 hour. After resetting, you'll need to sign in again on all devices.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Divider -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding: 24px 0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td height="1" bgcolor="#333344" style="background-color: #333344; font-size: 0; line-height: 0;"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Alternative Link -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center; line-height: 1.6;">
|
||||
If the button doesn't work, copy and paste this link into your browser:
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; text-align: center; word-break: break-all; line-height: 1.5;">
|
||||
<a href="{{ .ConfirmationURL }}" style="color: #e94560; text-decoration: underline;">{{ .ConfirmationURL }}</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td align="center" bgcolor="#0d0d1a" style="background-color: #0d0d1a; padding: 32px 20px;">
|
||||
<p style="margin: 0 0 8px 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #666677; text-align: center;">
|
||||
Didn't request this?
|
||||
</p>
|
||||
<p style="margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 12px; color: #555566; text-align: center;">
|
||||
If you didn't request a password reset, you can safely ignore this email. Your password won't change until you click the link above.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Spacer -->
|
||||
<tr>
|
||||
<td height="40" style="font-size: 0; line-height: 0;" bgcolor="#0d0d1a"> </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
# Copy this file to terraform.tfvars and fill in your values
|
||||
# NEVER commit terraform.tfvars to git!
|
||||
|
||||
supabase_access_token = "sbp_xxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
# OAuth provider credentials (optional - can also be set in Supabase dashboard)
|
||||
# google_client_id = ""
|
||||
# google_client_secret = ""
|
||||
# apple_client_id = ""
|
||||
# apple_client_secret = ""
|
||||
@@ -0,0 +1,68 @@
|
||||
variable "supabase_access_token" {
|
||||
description = "Supabase API access token"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
# Project refs per environment (selected by workspace)
|
||||
locals {
|
||||
project_refs = {
|
||||
production = "ckjcrkjpmhqhiucifukx"
|
||||
non-production = "itbzhrvlgvdmzbnhzhyx"
|
||||
default = "itbzhrvlgvdmzbnhzhyx" # Default workspace uses non-prod
|
||||
}
|
||||
|
||||
# Select project_ref based on current workspace
|
||||
project_ref = lookup(local.project_refs, terraform.workspace, local.project_refs["default"])
|
||||
|
||||
# Environment detection
|
||||
is_production = terraform.workspace == "production"
|
||||
|
||||
# SMTP settings (only production has custom SMTP configured)
|
||||
smtp_settings = local.is_production ? {
|
||||
smtp_admin_email = "team@send.sauci.app"
|
||||
smtp_host = "smtp.resend.com"
|
||||
smtp_max_frequency = 1
|
||||
smtp_port = "465"
|
||||
smtp_sender_name = "Sauci App"
|
||||
smtp_user = "resend"
|
||||
} : {}
|
||||
|
||||
# Rate limit for email (requires custom SMTP in production)
|
||||
rate_limit_email_sent = local.is_production ? 25 : 3
|
||||
}
|
||||
|
||||
variable "project_ref" {
|
||||
description = "Supabase project reference ID (overrides workspace-based selection)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
# Auth provider secrets (stored in Supabase dashboard, referenced here for documentation)
|
||||
variable "google_client_id" {
|
||||
description = "Google OAuth client ID"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "google_client_secret" {
|
||||
description = "Google OAuth client secret"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "apple_client_id" {
|
||||
description = "Apple OAuth client ID (Services ID)"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "apple_client_secret" {
|
||||
description = "Apple OAuth client secret (JWT)"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
|
||||
required_providers {
|
||||
supabase = {
|
||||
source = "supabase/supabase"
|
||||
version = "~> 1.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Store state remotely (recommended for team environments)
|
||||
# Uncomment and configure one of these backends:
|
||||
|
||||
# Option 1: Terraform Cloud
|
||||
# cloud {
|
||||
# organization = "your-org"
|
||||
# workspaces {
|
||||
# name = "sauci-production"
|
||||
# }
|
||||
# }
|
||||
|
||||
# Option 2: S3 backend
|
||||
# backend "s3" {
|
||||
# bucket = "your-terraform-state-bucket"
|
||||
# key = "sauci/production/terraform.tfstate"
|
||||
# region = "us-east-1"
|
||||
# }
|
||||
}
|
||||
|
||||
provider "supabase" {
|
||||
access_token = var.supabase_access_token
|
||||
}
|
||||
Reference in new issue
Block a user