mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-04 01:55:10 +02:00
fix minor auth issues and set NODE_ENV to solve react email bug
This commit is contained in:
parent
8178dd1525
commit
c2cbd7e1a1
10 changed files with 75 additions and 90 deletions
|
@ -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
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue