mirror of
https://github.com/swissmakers/swiss-datashare.git
synced 2026-04-05 07:47:01 +02:00
Merge branches 'main' and 'main' of https://github.com/stonith404/pingvin-share
This commit is contained in:
@@ -71,7 +71,6 @@ const configVariables: ConfigVariables = {
|
||||
enableShareEmailRecipients: {
|
||||
type: "boolean",
|
||||
defaultValue: "false",
|
||||
|
||||
secret: false,
|
||||
},
|
||||
shareRecipientsSubject: {
|
||||
@@ -148,6 +147,11 @@ const configVariables: ConfigVariables = {
|
||||
type: "boolean",
|
||||
defaultValue: "true",
|
||||
},
|
||||
"disablePassword": {
|
||||
type: "boolean",
|
||||
defaultValue: "false",
|
||||
secret: false,
|
||||
},
|
||||
"github-enabled": {
|
||||
type: "boolean",
|
||||
defaultValue: "false",
|
||||
@@ -229,7 +233,7 @@ const configVariables: ConfigVariables = {
|
||||
defaultValue: "",
|
||||
obscured: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
type ConfigVariables = {
|
||||
@@ -281,12 +285,15 @@ async function seedConfigVariables() {
|
||||
|
||||
async function migrateConfigVariables() {
|
||||
const existingConfigVariables = await prisma.config.findMany();
|
||||
const orderMap: { [category: string]: number } = {};
|
||||
|
||||
for (const existingConfigVariable of existingConfigVariables) {
|
||||
const configVariable =
|
||||
configVariables[existingConfigVariable.category]?.[
|
||||
existingConfigVariable.name
|
||||
existingConfigVariable.name
|
||||
];
|
||||
|
||||
// Delete the config variable if it doesn't exist in the seed
|
||||
if (!configVariable) {
|
||||
await prisma.config.delete({
|
||||
where: {
|
||||
@@ -297,15 +304,11 @@ async function migrateConfigVariables() {
|
||||
},
|
||||
});
|
||||
|
||||
// Update the config variable if the metadata changed
|
||||
} else if (
|
||||
JSON.stringify({
|
||||
...configVariable,
|
||||
name: existingConfigVariable.name,
|
||||
category: existingConfigVariable.category,
|
||||
value: existingConfigVariable.value,
|
||||
}) != JSON.stringify(existingConfigVariable)
|
||||
) {
|
||||
// Update the config variable if it exists in the seed
|
||||
} else {
|
||||
const variableOrder = Object.keys(
|
||||
configVariables[existingConfigVariable.category]
|
||||
).indexOf(existingConfigVariable.name);
|
||||
await prisma.config.update({
|
||||
where: {
|
||||
name_category: {
|
||||
@@ -318,8 +321,10 @@ async function migrateConfigVariables() {
|
||||
name: existingConfigVariable.name,
|
||||
category: existingConfigVariable.category,
|
||||
value: existingConfigVariable.value,
|
||||
order: variableOrder,
|
||||
},
|
||||
});
|
||||
orderMap[existingConfigVariable.category] = variableOrder + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,9 @@ export class AuthService {
|
||||
if (!dto.email && !dto.username)
|
||||
throw new BadRequestException("Email or username is required");
|
||||
|
||||
if (this.config.get("oauth.disablePassword"))
|
||||
throw new ForbiddenException("Password sign in is disabled");
|
||||
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
OR: [{ email: dto.email }, { username: dto.username }],
|
||||
@@ -102,6 +105,9 @@ export class AuthService {
|
||||
}
|
||||
|
||||
async requestResetPassword(email: string) {
|
||||
if (this.config.get("oauth.disablePassword"))
|
||||
throw new ForbiddenException("Password sign in is disabled");
|
||||
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: { email },
|
||||
include: { resetPasswordToken: true },
|
||||
@@ -127,6 +133,9 @@ export class AuthService {
|
||||
}
|
||||
|
||||
async resetPassword(token: string, newPassword: string) {
|
||||
if (this.config.get("oauth.disablePassword"))
|
||||
throw new ForbiddenException("Password sign in is disabled");
|
||||
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: { resetPasswordToken: { token } },
|
||||
});
|
||||
|
||||
@@ -28,6 +28,19 @@ import toast from "../../utils/toast.util";
|
||||
import { safeRedirectPath } from "../../utils/router.util";
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
signInWith: {
|
||||
fontWeight: 500,
|
||||
"&:before": {
|
||||
content: "''",
|
||||
flex: 1,
|
||||
display: "block",
|
||||
},
|
||||
"&:after": {
|
||||
content: "''",
|
||||
flex: 1,
|
||||
display: "block",
|
||||
},
|
||||
},
|
||||
or: {
|
||||
"&:before": {
|
||||
content: "''",
|
||||
@@ -128,49 +141,58 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => {
|
||||
</Text>
|
||||
)}
|
||||
<Paper withBorder shadow="md" p={30} mt={30} radius="md">
|
||||
<form
|
||||
onSubmit={form.onSubmit((values) => {
|
||||
signIn(values.emailOrUsername, values.password);
|
||||
})}
|
||||
>
|
||||
<TextInput
|
||||
label={t("signin.input.email-or-username")}
|
||||
placeholder={t("signin.input.email-or-username.placeholder")}
|
||||
{...form.getInputProps("emailOrUsername")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label={t("signin.input.password")}
|
||||
placeholder={t("signin.input.password.placeholder")}
|
||||
mt="md"
|
||||
{...form.getInputProps("password")}
|
||||
/>
|
||||
{config.get("smtp.enabled") && (
|
||||
<Group position="right" mt="xs">
|
||||
<Anchor component={Link} href="/auth/resetPassword" size="xs">
|
||||
<FormattedMessage id="resetPassword.title" />
|
||||
</Anchor>
|
||||
</Group>
|
||||
)}
|
||||
<Button fullWidth mt="xl" type="submit">
|
||||
<FormattedMessage id="signin.button.submit" />
|
||||
</Button>
|
||||
</form>
|
||||
{config.get("oauth.disablePassword") || (
|
||||
<form
|
||||
onSubmit={form.onSubmit((values) => {
|
||||
signIn(values.emailOrUsername, values.password);
|
||||
})}
|
||||
>
|
||||
<TextInput
|
||||
label={t("signin.input.email-or-username")}
|
||||
placeholder={t("signin.input.email-or-username.placeholder")}
|
||||
{...form.getInputProps("emailOrUsername")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label={t("signin.input.password")}
|
||||
placeholder={t("signin.input.password.placeholder")}
|
||||
mt="md"
|
||||
{...form.getInputProps("password")}
|
||||
/>
|
||||
{config.get("smtp.enabled") && (
|
||||
<Group position="right" mt="xs">
|
||||
<Anchor component={Link} href="/auth/resetPassword" size="xs">
|
||||
<FormattedMessage id="resetPassword.title" />
|
||||
</Anchor>
|
||||
</Group>
|
||||
)}
|
||||
<Button fullWidth mt="xl" type="submit">
|
||||
<FormattedMessage id="signin.button.submit" />
|
||||
</Button>
|
||||
</form>
|
||||
)}
|
||||
{oauth.length > 0 && (
|
||||
<Stack mt="xl">
|
||||
<Group align="center" className={classes.or}>
|
||||
<Text>{t("signIn.oauth.or")}</Text>
|
||||
</Group>
|
||||
<Stack mt={config.get("oauth.disablePassword") ? undefined : "xl"}>
|
||||
{config.get("oauth.disablePassword") ? (
|
||||
<Group align="center" className={classes.signInWith}>
|
||||
<Text>{t("signIn.oauth.signInWith")}</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<Group align="center" className={classes.or}>
|
||||
<Text>{t("signIn.oauth.or")}</Text>
|
||||
</Group>
|
||||
)}
|
||||
<Group position="center">
|
||||
{oauth.map((provider) => (
|
||||
<Button
|
||||
key={provider}
|
||||
component="a"
|
||||
target="_blank"
|
||||
title={t(`signIn.oauth.${provider}`)}
|
||||
href={getOAuthUrl(config.get("general.appUrl"), provider)}
|
||||
variant="light"
|
||||
fullWidth
|
||||
>
|
||||
{getOAuthIcon(provider)}
|
||||
{"\u2002" + t(`signIn.oauth.${provider}`)}
|
||||
</Button>
|
||||
))}
|
||||
</Group>
|
||||
|
||||
@@ -34,6 +34,7 @@ export default {
|
||||
"signIn.notify.totp-required.title": "Zwei-Faktor-Authentifizierung benötigt",
|
||||
"signIn.notify.totp-required.description": "Bitte füge deinen Zwei-Faktor-Authentifizierungscode ein",
|
||||
"signIn.oauth.or": "ODER",
|
||||
"signIn.oauth.signInWith": "Anmelden mit",
|
||||
"signIn.oauth.github": "GitHub",
|
||||
"signIn.oauth.google": "Google",
|
||||
"signIn.oauth.microsoft": "Microsoft",
|
||||
@@ -348,6 +349,9 @@ export default {
|
||||
"admin.config.oauth.allow-registration.description": "Benutzern erlauben, sich über Soziale Netzwerke zu registrieren",
|
||||
"admin.config.oauth.ignore-totp": "TOTP ignorieren",
|
||||
"admin.config.oauth.ignore-totp.description": "Gibt an, ob TOTP ignoriert werden soll, wenn sich der Benutzer über Soziale Netzwerke anmeldet",
|
||||
"admin.config.oauth.disable-password": "Anmelden mit Passwort deaktivieren",
|
||||
"admin.config.oauth.disable-password.description":
|
||||
"Deaktiviert das Anmelden mit Passwort\nStelle vor Aktivierung dieser Konfiguration sicher, dass ein OAuth-Provider korrekt konfiguriert ist, um nicht ausgesperrt zu werden.",
|
||||
"admin.config.oauth.github-enabled": "GitHub",
|
||||
"admin.config.oauth.github-enabled.description": "GitHub Anmeldung erlaubt",
|
||||
"admin.config.oauth.github-client-id": "GitHub Client-ID",
|
||||
@@ -401,7 +405,7 @@ export default {
|
||||
"error.msg.no_email": "Kann die E-Mail-Adresse von dem Konto {0} nicht abrufen.",
|
||||
"error.msg.already_linked": "Das Konto {0} ist bereits mit einem anderen Konto verknüpft.",
|
||||
"error.msg.not_linked": "Das Konto {0} wurde noch nicht mit einem Konto verknüpft.",
|
||||
"error.msg.unverified_account": "Dieses Konto {0} wurde noch nicht verifiziert, bitte versuchen Sie es nach der Verifikation erneut.",
|
||||
"error.msg.unverified_account": "Dieses Konto {0} wurde noch nicht verifiziert, bitte versuche es nach der Verifikation erneut.",
|
||||
"error.msg.discord_guild_permission_denied": "Du bist nicht berechtigt, Dich anzumelden.",
|
||||
"error.msg.cannot_get_user_info": "Deine Benutzerinformationen können nicht von diesem Konto {0} abgerufen werden.",
|
||||
"error.param.provider_github": "GitHub",
|
||||
|
||||
@@ -44,6 +44,7 @@ export default {
|
||||
"signIn.notify.totp-required.description":
|
||||
"Please enter your two-factor authentication code",
|
||||
"signIn.oauth.or": "OR",
|
||||
"signIn.oauth.signInWith": "Sign in with",
|
||||
"signIn.oauth.github": "GitHub",
|
||||
"signIn.oauth.google": "Google",
|
||||
"signIn.oauth.microsoft": "Microsoft",
|
||||
@@ -479,6 +480,9 @@ export default {
|
||||
"admin.config.oauth.ignore-totp": "Ignore TOTP",
|
||||
"admin.config.oauth.ignore-totp.description":
|
||||
"Whether to ignore TOTP when user using social login",
|
||||
"admin.config.oauth.disable-password": "Disable password login",
|
||||
"admin.config.oauth.disable-password.description":
|
||||
"Whether to disable password login\nMake sure that an OAuth provider is properly configured before activating this configuration to avoid being locked out.",
|
||||
"admin.config.oauth.github-enabled": "GitHub",
|
||||
"admin.config.oauth.github-enabled.description":
|
||||
"Whether GitHub login is enabled",
|
||||
|
||||
@@ -294,8 +294,8 @@ export default {
|
||||
"admin.config.general.app-url.description": "A Pingvin Share megosztáskezelőre mutató hivatkozás",
|
||||
"admin.config.general.show-home-page": "Kezdőlap mutatása",
|
||||
"admin.config.general.show-home-page.description": "A kezdőlap mutatásának ki- és bekapcsolása",
|
||||
"admin.config.general.session-duration": "Session Duration",
|
||||
"admin.config.general.session-duration.description": "Time in hours after which a user must log in again (default: 3 months).",
|
||||
"admin.config.general.session-duration": "Munkamenet időtartama",
|
||||
"admin.config.general.session-duration.description": "Annak az időtartamnak a megadása, amit követően a felhasználónak ismét be kell jelentkeznie (alapérték: 3 hónap).",
|
||||
"admin.config.general.logo": "Logó",
|
||||
"admin.config.general.logo.description": "A logó személyessé tételéhez töltsön fel egy új képet. A formátum legyen PNG, az oldalarány 1:1.",
|
||||
"admin.config.general.logo.placeholder": "Kép kiválasztása",
|
||||
|
||||
@@ -44,10 +44,10 @@ export default {
|
||||
"signup.title": "계정 만들기",
|
||||
"signup.description": "이미 계정이 있으신가요?",
|
||||
"signup.button.signin": "로그인",
|
||||
"signup.input.username": "사용자 이름",
|
||||
"signup.input.username.placeholder": "당신의 사용지 이름",
|
||||
"signup.input.username": "사용자명",
|
||||
"signup.input.username.placeholder": "귀하의 사용자명",
|
||||
"signup.input.email": "이메일",
|
||||
"signup.input.email.placeholder": "당신의 이메일",
|
||||
"signup.input.email.placeholder": "귀하의 이메일",
|
||||
"signup.button.submit": "시작하기",
|
||||
// END /auth/signup
|
||||
// /auth/totp
|
||||
@@ -258,13 +258,13 @@ export default {
|
||||
// /share/[id]
|
||||
"share.title": "공유 {shareId}",
|
||||
"share.description": "내가 당신과 공유한 것을 보세요!",
|
||||
"share.error.visitor-limit-exceeded.title": "방문자 제한 초과",
|
||||
"share.error.visitor-limit-exceeded.description": "The visitor limit from this share has been exceeded.",
|
||||
"share.error.visitor-limit-exceeded.title": "방문자 한도 초과",
|
||||
"share.error.visitor-limit-exceeded.description": "이 공유의 방문자 한도를 초과했습니다.",
|
||||
"share.error.removed.title": "공유가 삭제됨",
|
||||
"share.error.not-found.title": "공유를 찾을 수 없습니다.",
|
||||
"share.error.not-found.description": "당신이 찾는 공유는 존재하지 않습니다.",
|
||||
"share.modal.password.title": "비밀번호 필요",
|
||||
"share.modal.password.description": "이 공유에 액세스하려면 공유의 암호를 입력하십시오.",
|
||||
"share.modal.password.description": "이 공유에 접근하려면 공유의 암호를 입력하십시오.",
|
||||
"share.modal.password": "비밀번호",
|
||||
"share.modal.error.invalid-password": "잘못된 비밀번호",
|
||||
"share.button.download-all": "모두 다운로드",
|
||||
@@ -289,13 +289,13 @@ export default {
|
||||
"admin.config.category.smtp": "SMTP",
|
||||
"admin.config.category.oauth": "소셜 로그인",
|
||||
"admin.config.general.app-name": "앱 이름",
|
||||
"admin.config.general.app-name.description": "Name of the application",
|
||||
"admin.config.general.app-name.description": "이 앱의 이름",
|
||||
"admin.config.general.app-url": "앱 URL",
|
||||
"admin.config.general.app-url.description": "Pingvin Share를 사용할 수 있는 URL",
|
||||
"admin.config.general.show-home-page": "홈 페이지 표시",
|
||||
"admin.config.general.show-home-page.description": "홈 페이지를 표시할지 여부를 점검하십시오.",
|
||||
"admin.config.general.session-duration": "Session Duration",
|
||||
"admin.config.general.session-duration.description": "Time in hours after which a user must log in again (default: 3 months).",
|
||||
"admin.config.general.show-home-page.description": "홈 페이지를 표시할지 여부",
|
||||
"admin.config.general.session-duration": "세션 기간",
|
||||
"admin.config.general.session-duration.description": "사용자가 다시 로그인해야 하는 시간 (기본값: 3개월)",
|
||||
"admin.config.general.logo": "로고",
|
||||
"admin.config.general.logo.description": "새 이미지를 업로드하여 로고를 변경하십시오. 이미지는 PNG여야 하며 1:1 비율이어야 합니다.",
|
||||
"admin.config.general.logo.placeholder": "이미지 선택",
|
||||
@@ -305,9 +305,9 @@ export default {
|
||||
"admin.config.email.share-recipients-subject.description": "공유 수신자에게 전송되는 이메일의 제목입니다.",
|
||||
"admin.config.email.share-recipients-message": "수신자 메시지 공유",
|
||||
"admin.config.email.share-recipients-message.description": "공유 수신자에게 보내는 메시지입니다. 사용 가능한 변수:\n {creator} - 공유 작성자의 사용자 이름\n {shareUrl} - 공유의 URL\n {desc} - 공유에 대한 설명\n {expires} - 공유 만료일\n 변수는 실제 값으로 대체됩니다.",
|
||||
"admin.config.email.reverse-share-subject": "역공유 제목",
|
||||
"admin.config.email.reverse-share-subject": "역방향 공유 제목",
|
||||
"admin.config.email.reverse-share-subject.description": "누군가 당신이 공유한 역방향 공유 링크를 사용하여 공유를 생성했을 때 전송되는 이메일의 제목입니다.",
|
||||
"admin.config.email.reverse-share-message": "역공유 메시지",
|
||||
"admin.config.email.reverse-share-message": "역방향 공유 메시지",
|
||||
"admin.config.email.reverse-share-message.description": "누군가 귀하의 역방향 공유 링크를 사용하여 공유를 생성하면 전송되는 메시지입니다.. {shareUrl} 은 작성자 이름 및 공유 URL로 대체됩니다.",
|
||||
"admin.config.email.reset-password-subject": "비밀번호 재설정 제목",
|
||||
"admin.config.email.reset-password-subject.description": "사용자가 암호 재설정을 요청할 때 전송되는 메일의 제목입니다.",
|
||||
@@ -321,16 +321,16 @@ export default {
|
||||
"admin.config.share.allow-registration.description": "등록 가능 여부",
|
||||
"admin.config.share.allow-unauthenticated-shares": "인증되지 않은 공유 허용",
|
||||
"admin.config.share.allow-unauthenticated-shares.description": "인증되지 않은 사용자가 공유를 생성할 수 있는지 여부",
|
||||
"admin.config.share.max-expiration": "최대 만료일",
|
||||
"admin.config.share.max-expiration.description": "최대 공유 만료 시간입니다. 만료 기간을 설정하지 않는경우 0으로 설정합니다.",
|
||||
"admin.config.share.max-expiration": "최대 만료 시간",
|
||||
"admin.config.share.max-expiration.description": "공유의 최대 만료 시간. 무제한 만료를 허용하려면 0으로 설정하세요.",
|
||||
"admin.config.share.max-size": "최대 크기",
|
||||
"admin.config.share.max-size.description": "공유 최대 크기 - 바이트",
|
||||
"admin.config.share.zip-compression-level": "압축 레벨",
|
||||
"admin.config.share.max-size.description": "공유의 최대 크기 (바이트)",
|
||||
"admin.config.share.zip-compression-level": "Zip 압축 레벨",
|
||||
"admin.config.share.zip-compression-level.description": "파일 크기와 압축 속도 간의 균형을 맞추도록 레벨을 조정합니다. 유효한 값의 범위는 0에서 9까지이며, 0은 압축되지 않고 9는 최대 압축입니다. ",
|
||||
"admin.config.share.chunk-size": "청크 크기",
|
||||
"admin.config.share.chunk-size.description": "업로드할 청크 크기(바이트 단위)를 조정하여 인터넷 연결에 따라 효율성과 신뢰성의 균형을 유지합니다. 더 작은 청크는 불안정한 연결에 대한 성공률을 향상시킬 수 있고, 더 큰 청크는 안정적인 연결에 대한 업로드 속도를 높일 수 있습니다.",
|
||||
"admin.config.share.auto-open-share-modal": "Auto open create share modal",
|
||||
"admin.config.share.auto-open-share-modal.description": "The share creation modal automatically appears when a user selects files, eliminating the need to manually click the button.",
|
||||
"admin.config.share.auto-open-share-modal": "공유 생성 창 자동 열기",
|
||||
"admin.config.share.auto-open-share-modal.description": "사용자가 파일을 선택하면 공유 생성 창이 자동으로 나타나서 버튼을 수동으로 클릭할 필요가 없습니다.",
|
||||
"admin.config.smtp.enabled": "활성화됨",
|
||||
"admin.config.smtp.enabled.description": "SMTP 사용 여부 SMTP 서버의 호스트, 포트, 전자 메일, 사용자 및 암호를 입력한 경우에만 true로 설정합니다.",
|
||||
"admin.config.smtp.host": "호스트",
|
||||
|
||||
Reference in New Issue
Block a user