fixed redirect if logged out and added NEXTAUTH_URL if available

This commit is contained in:
biersoeckli
2024-11-22 10:22:49 +00:00
parent 1780f50bde
commit dc6e80834a
8 changed files with 51 additions and 30 deletions

View File

@@ -46,6 +46,7 @@ export default function UserLoginForm() {
username: data.email,
password: data.password,
redirect: true,
callbackUrl: "/",
});
} else {
setAuthInput(data); // 2fa window will be shown

View File

@@ -2,7 +2,7 @@
import userService from "@/server/services/user.service";
import UserRegistrationForm from "./register-from";
import UserLoginForm from "./login-from";
import UserLoginForm from "./login-form";
import { getUserSession } from "@/server/utils/action-wrapper.utils";
import { redirect } from "next/navigation";

View File

@@ -10,9 +10,11 @@ export const updateIngressSettings = async (prevState: any, inputData: QsIngress
saveFormAction(inputData, qsIngressSettingsZodModel, async (validatedData) => {
await getAuthUserSession();
const url = new URL(validatedData.serverUrl.includes('://') ? validatedData.serverUrl : `https://${validatedData.serverUrl}`);
await paramService.save({
name: ParamService.QS_SERVER_HOSTNAME,
value: validatedData.serverUrl
value: url.hostname
});
await paramService.save({
@@ -22,6 +24,8 @@ export const updateIngressSettings = async (prevState: any, inputData: QsIngress
await quickStackService.createOrUpdateService(!validatedData.disableNodePortAccess);
await quickStackService.createOrUpdateIngress(validatedData.serverUrl);
await quickStackService.createOrUpdateDeployment(url.hostname);
});
export const updateLetsEncryptSettings = async (prevState: any, inputData: QsLetsEncryptSettingsModel) =>

View File

@@ -2,7 +2,7 @@
import { SubmitButton } from "@/components/custom/submit-button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { FormUtils } from "@/lib/form.utilts";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
@@ -11,11 +11,7 @@ import { ServerActionResult } from "@/model/server-action-error-return.model";
import { Input } from "@/components/ui/input";
import { useEffect } from "react";
import { toast } from "sonner";
import { ProfilePasswordChangeModel, profilePasswordChangeZodModel } from "@/model/update-password.model";
import { QsIngressSettingsModel, qsIngressSettingsZodModel } from "@/model/qs-settings.model";
import { updateIngressSettings, updateLetsEncryptSettings } from "./actions";
import SelectFormField from "@/components/custom/select-form-field";
import CheckboxFormField from "@/components/custom/checkbox-form-field";
import { updateLetsEncryptSettings } from "./actions";
import { QsLetsEncryptSettingsModel, qsLetsEncryptSettingsZodModel } from "@/model/qs-letsencrypt-settings.model";
export default function QuickStackLetsEncryptSettings({

View File

@@ -1,6 +1,7 @@
export { default } from "next-auth/middleware"
export const config = {
matcher: ["/"],
exclude: ["/auth"]
matcher: ["/"],
exclude: ["/auth"],
}

View File

@@ -110,7 +110,7 @@ export class ParamService {
name: item.name as string
},
data: {
value: item.value
}
});
} else {

View File

@@ -18,7 +18,7 @@ class QuickStackService {
await namespaceService.createNamespaceIfNotExists(this.QUICKSTACK_NAMESPACE)
const nextAuthSecret = await this.deleteExistingDeployment();
await this.createOrUpdatePvc();
await this.createDeployment(nextAuthSecret);
await this.createOrUpdateDeployment(undefined, nextAuthSecret);
await this.createOrUpdateService(true);
console.log('QuickStack successfully initialized');
}
@@ -109,14 +109,14 @@ class QuickStackService {
}
};
// todo
/* const allIssuers = await k3s.network.clus();
const existingIssuer = allIssuers.body.items.find(i => i.metadata!.name === issuerName);
if (existingIssuer) {
await k3s.certManager.replaceClusterIssuer(issuerName, issuerDefinition);
console.log('Cert Issuer updated');
} else {
await k3s.certManager.createClusterIssuer(issuerDefinition);
console.log('Cert Issuer created');*/
/* const allIssuers = await k3s.network.clus();
const existingIssuer = allIssuers.body.items.find(i => i.metadata!.name === issuerName);
if (existingIssuer) {
await k3s.certManager.replaceClusterIssuer(issuerName, issuerDefinition);
console.log('Cert Issuer updated');
} else {
await k3s.certManager.createClusterIssuer(issuerDefinition);
console.log('Cert Issuer created');*/
}
async createOrUpdateService(openNodePort = false) {
@@ -155,7 +155,6 @@ class QuickStackService {
}
await k3s.core.createNamespacedService(this.QUICKSTACK_NAMESPACE, body);
console.log('Service created');
}
@@ -199,14 +198,18 @@ class QuickStackService {
}
private async createDeployment(existingNextAuthSecret?: string) {
async createOrUpdateDeployment(nextAuthHostname?: string, inputNextAuthSecret?: string) {
const generatedNextAuthSecret = crypto.randomBytes(32).toString('base64');
const existingDeployment = await this.getExistingDeployment();
const body: V1Deployment = {
metadata: {
name: this.QUICKSTACK_DEPLOYMENT_NAME,
},
spec: {
replicas: 1,
strategy: {
type: 'Recreate',
},
selector: {
matchLabels: {
app: this.QUICKSTACK_DEPLOYMENT_NAME
@@ -233,8 +236,12 @@ class QuickStackService {
env: [
{
name: 'NEXTAUTH_SECRET',
value: existingNextAuthSecret || generatedNextAuthSecret
}
value: inputNextAuthSecret || existingDeployment.nextAuthSecret || generatedNextAuthSecret
},
...nextAuthHostname ? [{
name: 'NEXTAUTH_URL',
value: `https://${nextAuthHostname}`
}] : []
],
volumeMounts: [{
name: 'quickstack-volume',
@@ -252,23 +259,34 @@ class QuickStackService {
}
}
};
await k3s.apps.createNamespacedDeployment(this.QUICKSTACK_NAMESPACE, body);
console.log('Deployment created');
if (existingDeployment.existingDeployments) {
await k3s.apps.replaceNamespacedDeployment(this.QUICKSTACK_DEPLOYMENT_NAME, this.QUICKSTACK_NAMESPACE, body);
console.log('Deployment updated');
} else {
await k3s.apps.createNamespacedDeployment(this.QUICKSTACK_NAMESPACE, body);
console.log('Deployment created');
}
}
/**
* @returns: the existing NEXTAUTH_SECRET if the deployment already exists
*/
private async deleteExistingDeployment() {
const allDeployments = await k3s.apps.listNamespacedDeployment(this.QUICKSTACK_NAMESPACE);
const existingDeployments = allDeployments.body.items.find(d => d.metadata!.name === this.QUICKSTACK_DEPLOYMENT_NAME);
const { existingDeployments, nextAuthSecret } = await this.getExistingDeployment();
const quickStackAlreadyDeployed = !!existingDeployments;
if (quickStackAlreadyDeployed) {
console.warn('QuickStack already deployed, deleting existing deployment (data wont be lost)');
await k3s.apps.deleteNamespacedDeployment(this.QUICKSTACK_DEPLOYMENT_NAME, this.QUICKSTACK_NAMESPACE);
console.log('Existing deployment deleted');
}
return existingDeployments?.spec?.template?.spec?.containers?.[0].env?.find(e => e.name === 'NEXTAUTH_SECRET')?.value;
return nextAuthSecret;
}
async getExistingDeployment() {
const allDeployments = await k3s.apps.listNamespacedDeployment(this.QUICKSTACK_NAMESPACE);
const existingDeployments = allDeployments.body.items.find(d => d.metadata!.name === this.QUICKSTACK_DEPLOYMENT_NAME);
const nextAuthSecret = existingDeployments?.spec?.template?.spec?.containers?.[0].env?.find(e => e.name === 'NEXTAUTH_SECRET')?.value;
return { existingDeployments, nextAuthSecret };
}
}

View File

@@ -25,7 +25,8 @@ export async function getUserSession(): Promise<UserSession | null> {
export async function getAuthUserSession(): Promise<UserSession> {
const session = await getUserSession();
if (!session) {
throw new ServiceException('User is not authenticated.');
console.error('User is not authenticated.');
redirect('/auth');
}
return session;
}