Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@
<script>
(function () {
var stored = localStorage.getItem("theme")
var dark = stored ? stored === "dark" : matchMedia("(prefers-color-scheme: dark)").matches
document.documentElement.classList.toggle("dark", dark)
document.documentElement.classList.toggle("dark", stored ? stored === "dark" : true)

var storedScheme = localStorage.getItem("colorScheme")
if (storedScheme) {
document.documentElement.setAttribute("data-scheme", storedScheme)
}
document.documentElement.setAttribute("data-scheme", storedScheme || "graphite")
})()
</script>
</head>
Expand Down
3 changes: 3 additions & 0 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { storeToRefs } from "pinia"
import { Toaster } from "vue-sonner"
import "vue-sonner/style.css"
import { useAuthStore } from "@/stores/auth"
import { useThemeStore } from "@/stores/theme"
import { router, PUBLIC_PATHS } from "@/router"

const authStore = useAuthStore()

useThemeStore()
const { accessToken } = storeToRefs(authStore)

watch(accessToken, (value) => {
Expand Down
4 changes: 2 additions & 2 deletions client/src/stores/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ export const COLOR_SCHEMES = [

export type ColorScheme = (typeof COLOR_SCHEMES)[number]["id"]

const DEFAULT_SCHEME: ColorScheme = "emerald"
const DEFAULT_SCHEME: ColorScheme = "graphite"

export function getSchemeMeta(id: string) {
return COLOR_SCHEMES.find((item) => item.id === id) ?? COLOR_SCHEMES[0]
}

export const useThemeStore = defineStore("theme", () => {
const isDark = useDark({ storageKey: "theme", initialValue: "light", disableTransition: false })
const isDark = useDark({ storageKey: "theme", initialValue: "dark", disableTransition: false })
const scheme = useStorage<ColorScheme>(SCHEME_KEY, DEFAULT_SCHEME)

watch(
Expand Down
34 changes: 21 additions & 13 deletions server/src/server/services/auth/create_user_email.html
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
<div style="margin:0;padding:32px 16px;background-color:#eff2f0;font-family:'Montserrat',Arial,sans-serif;">
<div style="margin:0;padding:32px 16px;background-color:#0a0a0b;font-family:'Montserrat',Arial,sans-serif;">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:480px;margin:0 auto;">
<tr>
<td style="padding-bottom:24px;text-align:center;">
<span style="font-size:22px;font-weight:700;color:#4f8a76;letter-spacing:0.5px;">Stankogram</span>
<span style="font-size:22px;font-weight:700;color:#5c8cf0;letter-spacing:0.5px;">Stankogram</span>
</td>
</tr>
<tr>
<td style="background-color:#ffffff;border-radius:20px;box-shadow:0 1px 2px rgba(0,0,0,0.04),0 12px 32px rgba(0,0,0,0.08);padding:36px 32px;">
<h1 style="margin:0 0 8px;font-size:20px;font-weight:700;color:#1e2422;">Добро пожаловать!</h1>
<p style="margin:0 0 28px;font-size:14px;line-height:1.6;color:#6b7a74;">Ваша учётная запись в Stankogram создана. Ниже — данные для входа.</p>
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f5f7f6;border-radius:14px;overflow:hidden;">
<td style="background-color:#212122;border-radius:20px;padding:36px 32px;">
<h1 style="margin:0 0 8px;font-size:20px;font-weight:700;color:#f4f4f5;">Добро пожаловать!</h1>
<p style="margin:0 0 28px;font-size:14px;line-height:1.6;color:#9ca3af;">Ваша учётная запись в Stankogram создана. Ниже — данные для входа.</p>
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#17181a;border-radius:14px;overflow:hidden;">
<tr>
<td style="padding:16px 20px;border-bottom:1px solid #e3e7e5;">
<div style="font-size:12px;color:#6b7a74;margin-bottom:4px;">Электронная почта</div>
<div style="font-size:15px;font-weight:600;color:#1e2422;">$email</div>
<td style="padding:16px 20px;border-bottom:1px solid #2e2e31;">
<div style="font-size:12px;color:#9ca3af;margin-bottom:4px;">Электронная почта</div>
<div style="font-size:15px;font-weight:600;color:#f4f4f5;">$email</div>
</td>
</tr>
<tr>
<td style="padding:16px 20px;">
<div style="font-size:12px;color:#6b7a74;margin-bottom:4px;">Пароль</div>
<div style="font-size:15px;font-weight:600;color:#4f8a76;letter-spacing:0.5px;font-family:monospace;">$password</div>
<div style="font-size:12px;color:#9ca3af;margin-bottom:4px;">Пароль</div>
<div style="font-size:15px;font-weight:600;color:#5c8cf0;letter-spacing:0.5px;font-family:monospace;">$password</div>
</td>
</tr>
</table>
<p style="margin:28px 0 0;font-size:12px;line-height:1.6;color:#6b7a74;">Никому не передавайте пароль. Если понадобится новый — воспользуйтесь сбросом пароля.</p>
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:28px auto 0;">
<tr>
<td style="border-radius:10px;background-color:#5c8cf0;">
<a href="$app_url" target="_blank" style="display:inline-block;padding:14px 36px;font-size:14px;font-weight:600;color:#0a0a0b;text-decoration:none;border-radius:10px;">Войти в Stankogram</a>
</td>
</tr>
</table>
<p style="margin:16px 0 0;font-size:12px;line-height:1.6;color:#9ca3af;text-align:center;">Или откройте вручную: <a href="$app_url" target="_blank" style="color:#5c8cf0;text-decoration:none;">$app_url</a></p>
<p style="margin:24px 0 0;font-size:12px;line-height:1.6;color:#9ca3af;">Никому не передавайте пароль. Если понадобится новый — воспользуйтесь сбросом пароля.</p>
</td>
</tr>
<tr>
<td style="padding-top:20px;text-align:center;">
<span style="font-size:12px;color:#6b7a74;">© Stankogram</span>
<span style="font-size:12px;color:#9ca3af;">© Stankogram</span>
</td>
</tr>
</table>
Expand Down
34 changes: 21 additions & 13 deletions server/src/server/services/auth/password_reset_confirm_email.html
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
<div style="margin:0;padding:32px 16px;background-color:#eff2f0;font-family:'Montserrat',Arial,sans-serif;">
<div style="margin:0;padding:32px 16px;background-color:#0a0a0b;font-family:'Montserrat',Arial,sans-serif;">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:480px;margin:0 auto;">
<tr>
<td style="padding-bottom:24px;text-align:center;">
<span style="font-size:22px;font-weight:700;color:#4f8a76;letter-spacing:0.5px;">Stankogram</span>
<span style="font-size:22px;font-weight:700;color:#5c8cf0;letter-spacing:0.5px;">Stankogram</span>
</td>
</tr>
<tr>
<td style="background-color:#ffffff;border-radius:20px;box-shadow:0 1px 2px rgba(0,0,0,0.04),0 12px 32px rgba(0,0,0,0.08);padding:36px 32px;">
<h1 style="margin:0 0 8px;font-size:20px;font-weight:700;color:#1e2422;">Пароль изменён</h1>
<p style="margin:0 0 28px;font-size:14px;line-height:1.6;color:#6b7a74;">Пароль от вашей учётной записи в Stankogram успешно сброшен. Новые данные для входа — ниже.</p>
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f5f7f6;border-radius:14px;overflow:hidden;">
<td style="background-color:#212122;border-radius:20px;padding:36px 32px;">
<h1 style="margin:0 0 8px;font-size:20px;font-weight:700;color:#f4f4f5;">Пароль изменён</h1>
<p style="margin:0 0 28px;font-size:14px;line-height:1.6;color:#9ca3af;">Пароль от вашей учётной записи в Stankogram успешно сброшен. Новые данные для входа — ниже.</p>
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#17181a;border-radius:14px;overflow:hidden;">
<tr>
<td style="padding:16px 20px;border-bottom:1px solid #e3e7e5;">
<div style="font-size:12px;color:#6b7a74;margin-bottom:4px;">Электронная почта</div>
<div style="font-size:15px;font-weight:600;color:#1e2422;">$email</div>
<td style="padding:16px 20px;border-bottom:1px solid #2e2e31;">
<div style="font-size:12px;color:#9ca3af;margin-bottom:4px;">Электронная почта</div>
<div style="font-size:15px;font-weight:600;color:#f4f4f5;">$email</div>
</td>
</tr>
<tr>
<td style="padding:16px 20px;">
<div style="font-size:12px;color:#6b7a74;margin-bottom:4px;">Новый пароль</div>
<div style="font-size:15px;font-weight:600;color:#4f8a76;letter-spacing:0.5px;font-family:monospace;">$password</div>
<div style="font-size:12px;color:#9ca3af;margin-bottom:4px;">Новый пароль</div>
<div style="font-size:15px;font-weight:600;color:#5c8cf0;letter-spacing:0.5px;font-family:monospace;">$password</div>
</td>
</tr>
</table>
<p style="margin:28px 0 0;font-size:12px;line-height:1.6;color:#6b7a74;">Никому не передавайте пароль. Если это были не вы — срочно свяжитесь с поддержкой.</p>
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:28px auto 0;">
<tr>
<td style="border-radius:10px;background-color:#5c8cf0;">
<a href="$app_url" target="_blank" style="display:inline-block;padding:14px 36px;font-size:14px;font-weight:600;color:#0a0a0b;text-decoration:none;border-radius:10px;">Войти в Stankogram</a>
</td>
</tr>
</table>
<p style="margin:16px 0 0;font-size:12px;line-height:1.6;color:#9ca3af;text-align:center;">Или откройте вручную: <a href="$app_url" target="_blank" style="color:#5c8cf0;text-decoration:none;">$app_url</a></p>
<p style="margin:24px 0 0;font-size:12px;line-height:1.6;color:#9ca3af;">Никому не передавайте пароль. Если это были не вы — срочно свяжитесь с поддержкой.</p>
</td>
</tr>
<tr>
<td style="padding-top:20px;text-align:center;">
<span style="font-size:12px;color:#6b7a74;">© Stankogram</span>
<span style="font-size:12px;color:#9ca3af;">© Stankogram</span>
</td>
</tr>
</table>
Expand Down
20 changes: 10 additions & 10 deletions server/src/server/services/auth/password_reset_email.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
<div style="margin:0;padding:32px 16px;background-color:#eff2f0;font-family:'Montserrat',Arial,sans-serif;">
<div style="margin:0;padding:32px 16px;background-color:#0a0a0b;font-family:'Montserrat',Arial,sans-serif;">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:480px;margin:0 auto;">
<tr>
<td style="padding-bottom:24px;text-align:center;">
<span style="font-size:22px;font-weight:700;color:#4f8a76;letter-spacing:0.5px;">Stankogram</span>
<span style="font-size:22px;font-weight:700;color:#5c8cf0;letter-spacing:0.5px;">Stankogram</span>
</td>
</tr>
<tr>
<td style="background-color:#ffffff;border-radius:20px;box-shadow:0 1px 2px rgba(0,0,0,0.04),0 12px 32px rgba(0,0,0,0.08);padding:36px 32px;">
<h1 style="margin:0 0 8px;font-size:20px;font-weight:700;color:#1e2422;">Сброс пароля</h1>
<p style="margin:0 0 28px;font-size:14px;line-height:1.6;color:#6b7a74;">Мы получили запрос на сброс пароля в Stankogram. Нажмите на кнопку ниже, чтобы подтвердить действие.</p>
<td style="background-color:#212122;border-radius:20px;padding:36px 32px;">
<h1 style="margin:0 0 8px;font-size:20px;font-weight:700;color:#f4f4f5;">Сброс пароля</h1>
<p style="margin:0 0 28px;font-size:14px;line-height:1.6;color:#9ca3af;">Мы получили запрос на сброс пароля в Stankogram. Нажмите на кнопку ниже, чтобы подтвердить действие.</p>
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:0 auto;">
<tr>
<td style="border-radius:10px;background-color:#4f8a76;">
<a href="$url" target="_blank" style="display:inline-block;padding:14px 36px;font-size:14px;font-weight:600;color:#ffffff;text-decoration:none;border-radius:10px;">Подтвердить</a>
<td style="border-radius:10px;background-color:#5c8cf0;">
<a href="$url" target="_blank" style="display:inline-block;padding:14px 36px;font-size:14px;font-weight:600;color:#0a0a0b;text-decoration:none;border-radius:10px;">Подтвердить</a>
</td>
</tr>
</table>
<p style="margin:20px 0 0;font-size:12px;line-height:1.6;color:#4f8a76;font-weight:600;text-align:center;">Ссылка действительна 10 минут</p>
<p style="margin:20px 0 0;font-size:12px;line-height:1.6;color:#6b7a74;">Если вы не запрашивали сброс пароля, просто проигнорируйте это письмо — доступ к аккаунту сохранится без изменений.</p>
<p style="margin:20px 0 0;font-size:12px;line-height:1.6;color:#5c8cf0;font-weight:600;text-align:center;">Ссылка действительна 10 минут</p>
<p style="margin:20px 0 0;font-size:12px;line-height:1.6;color:#9ca3af;">Если вы не запрашивали сброс пароля, просто проигнорируйте это письмо — доступ к аккаунту сохранится без изменений.</p>
</td>
</tr>
<tr>
<td style="padding-top:20px;text-align:center;">
<span style="font-size:12px;color:#6b7a74;">© Stankogram</span>
<span style="font-size:12px;color:#9ca3af;">© Stankogram</span>
</td>
</tr>
</table>
Expand Down
6 changes: 4 additions & 2 deletions server/src/server/services/auth/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ def _generate_password_reset_code() -> str:

@staticmethod
def _generate_create_email(email: str, password: str) -> str:
return _CREATE_USER_EMAIL_TEMPLATE.substitute(email=email, password=password)
return _CREATE_USER_EMAIL_TEMPLATE.substitute(
email=email, password=password, app_url=APP_BASE_URL
)

@staticmethod
def _generate_password_reset_email(user_id: int, code: str) -> str:
Expand All @@ -68,7 +70,7 @@ def _generate_password_reset_email(user_id: int, code: str) -> str:
@staticmethod
def _generate_password_reset_confirm_email(email: str, password: str) -> str:
return _PASSWORD_RESET_CONFIRM_EMAIL_TEMPLATE.substitute(
email=email, password=password
email=email, password=password, app_url=APP_BASE_URL
)

@staticmethod
Expand Down