fix minor auth issues and set NODE_ENV to solve react email bug

This commit is contained in:
Milo Schwartz 2024-11-27 14:35:38 -05:00
parent 8178dd1525
commit c2cbd7e1a1
No known key found for this signature in database
10 changed files with 75 additions and 90 deletions

View file

@ -1,14 +1,15 @@
app:
base_url: http://localhost:3000
base_url: https://fossorial.io
log_level: debug
save_logs: false
server:
external_port: 3000
internal_port: 3001
internal_hostname: localhost
internal_hostname: pangolin
secure_cookies: false
session_cookie_name: session
resource_session_cookie_name: resource_session
traefik:
cert_resolver: letsencrypt
@ -16,16 +17,12 @@ traefik:
https_entrypoint: websecure
prefer_wildcard_cert: true
badger:
session_query_parameter: __pang_sess
resource_session_cookie_name: resource_session
gerbil:
start_port: 51820
base_endpoint: localhost
base_endpoint: fossorial.io
use_subdomain: false
block_size: 16
subnet_group: 10.0.0.0/8
use_subdomain: true
rate_limit:
window_minutes: 1

View file

@ -10,7 +10,7 @@
"db:hydrate": "npx tsx scripts/hydrate.ts",
"db:studio": "drizzle-kit studio",
"build": "mkdir -p dist && next build && node scripts/esbuild.mjs -e server/index.ts -o dist/server.mjs",
"start": "ENVIRONMENT=prod node dist/server.mjs",
"start": "NODE_ENV=development ENVIRONMENT=prod node dist/server.mjs",
"email": "email dev --dir server/emails/templates --port 3002"
},
"dependencies": {

View file

@ -25,9 +25,6 @@ const environmentSchema = z.object({
secure_cookies: z.boolean(),
signup_secret: z.string().optional(),
session_cookie_name: z.string(),
}),
badger: z.object({
session_query_parameter: z.string(),
resource_session_cookie_name: z.string(),
}),
traefik: z.object({
@ -136,8 +133,6 @@ process.env.FLAGS_EMAIL_VERIFICATION_REQUIRED = parsedConfig.data.flags
: "false";
process.env.SESSION_COOKIE_NAME = parsedConfig.data.server.session_cookie_name;
process.env.RESOURCE_SESSION_COOKIE_NAME =
parsedConfig.data.badger.resource_session_cookie_name;
process.env.RESOURCE_SESSION_QUERY_PARAM_NAME =
parsedConfig.data.badger.session_query_parameter;
parsedConfig.data.server.resource_session_cookie_name;
export default parsedConfig.data;

View file

@ -121,7 +121,7 @@ export async function verifyResourceSession(
const resourceSessionToken =
sessions[
`${config.badger.resource_session_cookie_name}_${resource.resourceId}`
`${config.server.resource_session_cookie_name}_${resource.resourceId}`
];
if ((pincode || password) && resourceSessionToken) {

View file

@ -132,7 +132,7 @@ export async function authWithPassword(
token,
passwordId: definedPassword.passwordId,
});
const cookieName = `${config.badger.resource_session_cookie_name}_${resource.resourceId}`;
const cookieName = `${config.server.resource_session_cookie_name}_${resource.resourceId}`;
const cookie = serializeResourceSessionCookie(
cookieName,
token,

View file

@ -128,7 +128,7 @@ export async function authWithPincode(
token,
pincodeId: definedPincode.pincodeId,
});
const cookieName = `${config.badger.resource_session_cookie_name}_${resource.resourceId}`;
const cookieName = `${config.server.resource_session_cookie_name}_${resource.resourceId}`;
const cookie = serializeResourceSessionCookie(
cookieName,
token,

View file

@ -55,11 +55,9 @@ export async function traefikConfigProvider(
`http://${config.server.internal_hostname}:${config.server.internal_port}`,
).href,
resourceSessionCookieName:
config.badger.resource_session_cookie_name,
config.server.resource_session_cookie_name,
userSessionCookieName:
config.server.session_cookie_name,
sessionQueryParameter:
config.badger.session_query_parameter,
},
},
},

View file

@ -233,6 +233,24 @@ export default function ReverseProxyTargets(props: {
}
const columns: ColumnDef<LocalTarget>[] = [
{
accessorKey: "method",
header: "Method",
cell: ({ row }) => (
<Select
defaultValue={row.original.method}
onValueChange={(value) =>
updateTarget(row.original.targetId, { method: value })
}
>
<SelectTrigger>{row.original.method}</SelectTrigger>
<SelectContent>
<SelectItem value="http">http</SelectItem>
<SelectItem value="https">https</SelectItem>
</SelectContent>
</Select>
),
},
{
accessorKey: "ip",
header: "IP Address",
@ -262,24 +280,6 @@ export default function ReverseProxyTargets(props: {
/>
),
},
{
accessorKey: "method",
header: "Method",
cell: ({ row }) => (
<Select
defaultValue={row.original.method}
onValueChange={(value) =>
updateTarget(row.original.targetId, { method: value })
}
>
<SelectTrigger>{row.original.method}</SelectTrigger>
<SelectContent>
<SelectItem value="http">http</SelectItem>
<SelectItem value="https">https</SelectItem>
</SelectContent>
</Select>
),
},
// {
// accessorKey: "protocol",
// header: "Protocol",
@ -368,7 +368,7 @@ export default function ReverseProxyTargets(props: {
</div>
</section>
<hr className="lg:max-w-2xl"/>
<hr className="lg:max-w-2xl" />
<section className="space-y-8">
<SettingsSectionTitle
@ -386,25 +386,6 @@ export default function ReverseProxyTargets(props: {
className="space-y-8"
>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
<FormField
control={addTargetForm.control}
name="ip"
render={({ field }) => (
<FormItem>
<FormLabel>
IP Address
</FormLabel>
<FormControl>
<Input id="ip" {...field} />
</FormControl>
<FormDescription>
Enter the IP address of the
target.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={addTargetForm.control}
name="method"
@ -444,6 +425,25 @@ export default function ReverseProxyTargets(props: {
</FormItem>
)}
/>
<FormField
control={addTargetForm.control}
name="ip"
render={({ field }) => (
<FormItem>
<FormLabel>
IP Address
</FormLabel>
<FormControl>
<Input id="ip" {...field} />
</FormControl>
<FormDescription>
Enter the IP address of the
target.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={addTargetForm.control}
name="port"

View file

@ -165,14 +165,14 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
};
async function handleSSOAuth() {
console.log("SSO authentication");
await api.get(`/resource/${props.resource.id}`).catch((e) => {
try {
await api.get(`/resource/${props.resource.id}`);
} catch (e) {
setAccessDenied(true);
});
}
if (!accessDenied) {
window.location.href = props.redirect;
window.location.href = constructRedirect(props.redirect);
}
}

View file

@ -65,9 +65,7 @@ export default async function ResourceAuthPage(props: {
if (res && res.data.data.valid) {
doRedirect = true;
}
} catch (e) {
console.error(e);
}
} catch (e) {}
if (doRedirect) {
redirect(redirectUrl);
@ -91,7 +89,6 @@ export default async function ResourceAuthPage(props: {
console.log(res.data);
doRedirect = true;
} catch (e) {
console.error(e);
userIsUnauthorized = true;
}
@ -100,30 +97,28 @@ export default async function ResourceAuthPage(props: {
}
}
if (userIsUnauthorized && isSSOOnly) {
return (
<div className="w-full max-w-md">
<ResourceAccessDenied />
</div>
);
}
return (
<>
<div className="w-full max-w-md">
<ResourceAuthPortal
methods={{
password: authInfo.password,
pincode: authInfo.pincode,
sso: authInfo.sso && !userIsUnauthorized,
}}
resource={{
name: authInfo.resourceName,
id: authInfo.resourceId,
}}
redirect={redirectUrl}
/>
</div>
{userIsUnauthorized && isSSOOnly ? (
<div className="w-full max-w-md">
<ResourceAccessDenied />
</div>
) : (
<div className="w-full max-w-md">
<ResourceAuthPortal
methods={{
password: authInfo.password,
pincode: authInfo.pincode,
sso: authInfo.sso && !userIsUnauthorized,
}}
resource={{
name: authInfo.resourceName,
id: authInfo.resourceId,
}}
redirect={redirectUrl}
/>
</div>
)}
</>
);
}