1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-05 21:45:25 +02:00

feat: auto detect first login (#2722)

* 'hide' default email and password env variables

* first login API endpoint

* run code-generators

* frontend indicators for default username and pw

* remove old env variables from docs

* fix env set variable

* remove password from tests
This commit is contained in:
Hayden 2023-11-15 09:24:24 -06:00 committed by GitHub
parent 71f95ca3c6
commit bc575ec5ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 234 additions and 120 deletions

View file

@ -3,117 +3,117 @@ export const LOCALES = [
{
name: "繁體中文 (Chinese traditional)",
value: "zh-TW",
progress: 26,
progress: 28,
},
{
name: "简体中文 (Chinese simplified)",
value: "zh-CN",
progress: 34,
progress: 65,
},
{
name: "Tiếng Việt (Vietnamese)",
value: "vi-VN",
progress: 0,
progress: 2,
},
{
name: "Українська (Ukrainian)",
value: "uk-UA",
progress: 100,
progress: 99,
},
{
name: "Türkçe (Turkish)",
value: "tr-TR",
progress: 47,
progress: 50,
},
{
name: "Svenska (Swedish)",
value: "sv-SE",
progress: 60,
progress: 71,
},
{
name: "српски (Serbian)",
value: "sr-SP",
progress: 2,
progress: 4,
},
{
name: "Slovenian",
value: "sl-SI",
progress: 47,
progress: 49,
},
{
name: "Slovak",
value: "sk-SK",
progress: 99,
progress: 97,
},
{
name: "Pусский (Russian)",
value: "ru-RU",
progress: 31,
progress: 99,
},
{
name: "Română (Romanian)",
value: "ro-RO",
progress: 12,
progress: 32,
},
{
name: "Português (Portuguese)",
value: "pt-PT",
progress: 69,
progress: 99,
},
{
name: "Português do Brasil (Brazilian Portuguese)",
value: "pt-BR",
progress: 97,
progress: 98,
},
{
name: "Polski (Polish)",
value: "pl-PL",
progress: 99,
progress: 97,
},
{
name: "Norsk (Norwegian)",
value: "no-NO",
progress: 73,
progress: 85,
},
{
name: "Nederlands (Dutch)",
value: "nl-NL",
progress: 100,
progress: 98,
},
{
name: "Latvian",
value: "lv-LV",
progress: 0,
progress: 1,
},
{
name: "Lithuanian",
value: "lt-LT",
progress: 99,
progress: 97,
},
{
name: "한국어 (Korean)",
value: "ko-KR",
progress: 3,
progress: 5,
},
{
name: "日本語 (Japanese)",
value: "ja-JP",
progress: 9,
progress: 11,
},
{
name: "Italiano (Italian)",
value: "it-IT",
progress: 98,
progress: 96,
},
{
name: "Magyar (Hungarian)",
value: "hu-HU",
progress: 43,
progress: 99,
},
{
name: "Croatian",
value: "hr-HR",
progress: 100,
progress: 97,
},
{
name: "עברית (Hebrew)",
@ -123,27 +123,27 @@ export const LOCALES = [
{
name: "Galician",
value: "gl-ES",
progress: 0,
progress: 1,
},
{
name: "Français (French)",
value: "fr-FR",
progress: 100,
progress: 99,
},
{
name: "French, Canada",
value: "fr-CA",
progress: 54,
progress: 97,
},
{
name: "Suomi (Finnish)",
value: "fi-FI",
progress: 31,
progress: 95,
},
{
name: "Español (Spanish)",
value: "es-ES",
progress: 59,
progress: 76,
},
{
name: "American English",
@ -153,46 +153,46 @@ export const LOCALES = [
{
name: "British English",
value: "en-GB",
progress: 2,
progress: 4,
},
{
name: "Ελληνικά (Greek)",
value: "el-GR",
progress: 33,
progress: 35,
},
{
name: "Deutsch (German)",
value: "de-DE",
progress: 100,
progress: 99,
},
{
name: "Dansk (Danish)",
value: "da-DK",
progress: 90,
progress: 100,
},
{
name: "Čeština (Czech)",
value: "cs-CZ",
progress: 60,
progress: 66,
},
{
name: "Català (Catalan)",
value: "ca-ES",
progress: 54,
progress: 61,
},
{
name: "Bulgarian",
value: "bg-BG",
progress: 13,
progress: 99,
},
{
name: "العربية (Arabic)",
value: "ar-SA",
progress: 7,
progress: 16,
},
{
name: "Afrikaans (Afrikaans)",
value: "af-ZA",
progress: 0,
progress: 96,
},
]

View file

@ -868,7 +868,9 @@
"user-can-invite-other-to-group": "User can invite other to group",
"user-can-manage-group": "User can manage group",
"user-can-organize-group-data": "User can organize group data",
"enable-advanced-features": "Enable advanced features"
"enable-advanced-features": "Enable advanced features",
"it-looks-like-this-is-your-first-time-logging-in": "It looks like this is your first time logging in.",
"dont-want-to-see-this-anymore-be-sure-to-change-your-email": "Don't want to see this anymore? Be sure to change your email in your user settings!"
},
"language-dialog": {
"translated": "translated",

View file

@ -34,6 +34,9 @@ export interface AppInfo {
demoStatus: boolean;
allowSignup: boolean;
}
export interface AppStartupInfo {
isFirstLogin: boolean;
}
export interface AppStatistics {
totalRecipes: number;
totalUsers: number;
@ -41,6 +44,22 @@ export interface AppStatistics {
uncategorizedRecipes: number;
untaggedRecipes: number;
}
export interface AppTheme {
lightPrimary?: string;
lightAccent?: string;
lightSecondary?: string;
lightSuccess?: string;
lightInfo?: string;
lightWarning?: string;
lightError?: string;
darkPrimary?: string;
darkAccent?: string;
darkSecondary?: string;
darkSuccess?: string;
darkInfo?: string;
darkWarning?: string;
darkError?: string;
}
export interface BackupOptions {
recipes?: boolean;
settings?: boolean;

View file

@ -6,7 +6,14 @@
*/
export type WebhookType = "mealplan";
export type SupportedMigrations = "nextcloud" | "chowdown" | "copymethat" | "paprika" | "mealie_alpha" | "tandoor" | "plantoeat";
export type SupportedMigrations =
| "nextcloud"
| "chowdown"
| "copymethat"
| "paprika"
| "mealie_alpha"
| "tandoor"
| "plantoeat";
export interface CreateGroupPreferences {
privateGroup?: boolean;
@ -263,39 +270,56 @@ export interface RecipeIngredient {
}
export interface IngredientUnit {
name: string;
pluralName?: string;
description?: string;
extras?: {
[k: string]: unknown;
};
fraction?: boolean;
abbreviation?: string;
pluralAbbreviation?: string;
useAbbreviation?: boolean;
aliases?: IngredientUnitAlias[];
id: string;
createdAt?: string;
updateAt?: string;
}
export interface IngredientUnitAlias {
name: string;
}
export interface CreateIngredientUnit {
name: string;
pluralName?: string;
description?: string;
extras?: {
[k: string]: unknown;
};
fraction?: boolean;
abbreviation?: string;
pluralAbbreviation?: string;
useAbbreviation?: boolean;
aliases?: CreateIngredientUnitAlias[];
}
export interface CreateIngredientUnitAlias {
name: string;
}
export interface IngredientFood {
name: string;
pluralName?: string;
description?: string;
extras?: {
[k: string]: unknown;
};
labelId?: string;
aliases?: IngredientFoodAlias[];
id: string;
label?: MultiPurposeLabelSummary;
createdAt?: string;
updateAt?: string;
}
export interface IngredientFoodAlias {
name: string;
}
export interface MultiPurposeLabelSummary {
name: string;
color?: string;
@ -304,11 +328,16 @@ export interface MultiPurposeLabelSummary {
}
export interface CreateIngredientFood {
name: string;
pluralName?: string;
description?: string;
extras?: {
[k: string]: unknown;
};
labelId?: string;
aliases?: CreateIngredientFoodAlias[];
}
export interface CreateIngredientFoodAlias {
name: string;
}
export interface ShoppingListCreate {
name?: string;

View file

@ -465,7 +465,7 @@ export interface ScrapeRecipe {
export interface ScrapeRecipeTest {
url: string;
}
export interface SlugResponse { }
export interface SlugResponse {}
export interface TagIn {
name: string;
}

View file

@ -5,6 +5,7 @@
/* Do not modify it by hand - just update the pydantic models and then re-run the script
*/
export type OrderByNullPosition = "first" | "last";
export type OrderDirection = "asc" | "desc";
export interface ErrorResponse {
@ -19,6 +20,7 @@ export interface PaginationQuery {
page?: number;
perPage?: number;
orderBy?: string;
orderByNullPosition?: OrderByNullPosition;
orderDirection?: OrderDirection & string;
queryFilter?: string;
paginationSeed?: string;

View file

@ -7,6 +7,18 @@
'bg-off-white': !$vuetify.theme.dark && !isDark,
}"
>
<v-alert v-if="isFirstLogin" class="my-4" type="info" icon="mdi-information">
<div>
<p class="mb-3">
{{ $tc('user.it-looks-like-this-is-your-first-time-logging-in')}}
</p>
<p class="mb-1"><strong>{{ $tc('user.username') }}:</strong> changeme@example.com</p>
<p class="mb-3"><strong>{{ $tc('user.password') }}:</strong> MyPassword</p>
<p>
{{ $tc('user.dont-want-to-see-this-anymore-be-sure-to-change-your-email') }}
</p>
</div>
</v-alert>
<v-card tag="section" class="d-flex flex-column align-center" width="600px">
<v-toolbar width="100%" color="primary" class="d-flex justify-center mb-4" dark>
<v-toolbar-title class="headline text-h4"> Mealie </v-toolbar-title>
@ -101,12 +113,14 @@
</template>
<script lang="ts">
import { defineComponent, ref, useContext, computed, reactive, useRouter } from "@nuxtjs/composition-api";
import { defineComponent, ref, useContext, computed, reactive, useRouter, useAsync } from "@nuxtjs/composition-api";
import { useDark, whenever } from "@vueuse/core";
import { useLoggedInState } from "~/composables/use-logged-in-state";
import { useAppInfo } from "~/composables/api";
import { usePasswordField } from "~/composables/use-passwords";
import { alert } from "~/composables/use-toast";
import { useAsyncKey } from "~/composables/use-utils";
import { AppStartupInfo } from "~/lib/api/types/admin";
export default defineComponent({
layout: "blank",
@ -115,7 +129,7 @@ export default defineComponent({
const isDark = useDark();
const router = useRouter();
const { $auth, i18n } = useContext();
const { $auth, i18n, $axios } = useContext();
const { loggedIn } = useLoggedInState();
const groupSlug = computed(() => $auth.user?.groupSlug);
@ -133,6 +147,13 @@ export default defineComponent({
remember: false,
});
const isFirstLogin = ref(false)
useAsync(async () => {
const data = await $axios.get<AppStartupInfo>("/api/app/about/startup-info");
isFirstLogin.value = data.data.isFirstLogin;
}, useAsyncKey());
const loggingIn = ref(false);
const appInfo = useAppInfo();
@ -182,6 +203,7 @@ export default defineComponent({
passwordIcon,
inputType,
togglePasswordShow,
isFirstLogin
};
},