mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(user-auth): make users auth token expiration customizable for orgs
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { TableName } from "../schemas";
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
if (!(await knex.schema.hasColumn(TableName.Organization, "userTokenExpiration"))) {
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.string("userTokenExpiration").defaultTo("30d").notNullable();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
if (await knex.schema.hasColumn(TableName.Organization, "userTokenExpiration")) {
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.dropColumn("userTokenExpiration");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,8 @@ export const OrganizationsSchema = z.object({
|
||||
shouldUseNewPrivilegeSystem: z.boolean().default(true),
|
||||
privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(),
|
||||
privilegeUpgradeInitiatedAt: z.date().nullable().optional(),
|
||||
bypassOrgAuthEnabled: z.boolean().default(false)
|
||||
bypassOrgAuthEnabled: z.boolean().default(false),
|
||||
userTokenExpiration: z.string().default("30d")
|
||||
});
|
||||
|
||||
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
|
||||
|
||||
@@ -79,6 +79,18 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => {
|
||||
handler: async (req) => {
|
||||
const { decodedToken, tokenVersion } = await server.services.authToken.validateRefreshToken(req.cookies.jid);
|
||||
const appCfg = getConfig();
|
||||
let expiresIn = appCfg.JWT_AUTH_LIFETIME;
|
||||
if (decodedToken.organizationId) {
|
||||
const org = await server.services.org.findOrganizationById(
|
||||
decodedToken.userId,
|
||||
decodedToken.organizationId,
|
||||
decodedToken.authMethod,
|
||||
decodedToken.organizationId
|
||||
);
|
||||
if (org) {
|
||||
expiresIn = org.userTokenExpiration;
|
||||
}
|
||||
}
|
||||
|
||||
const token = jwt.sign(
|
||||
{
|
||||
@@ -92,7 +104,7 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => {
|
||||
mfaMethod: decodedToken.mfaMethod
|
||||
},
|
||||
appCfg.AUTH_SECRET,
|
||||
{ expiresIn: appCfg.JWT_AUTH_LIFETIME }
|
||||
{ expiresIn }
|
||||
);
|
||||
|
||||
return { token, organizationId: decodedToken.organizationId };
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import RE2 from "re2";
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
@@ -263,7 +264,18 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
enforceMfa: z.boolean().optional(),
|
||||
selectedMfaMethod: z.nativeEnum(MfaMethod).optional(),
|
||||
allowSecretSharingOutsideOrganization: z.boolean().optional(),
|
||||
bypassOrgAuthEnabled: z.boolean().optional()
|
||||
bypassOrgAuthEnabled: z.boolean().optional(),
|
||||
userTokenExpiration: z
|
||||
.string()
|
||||
.regex(new RE2(/^\d+[mhdw]$/), "Must be a number followed by m, h, d, or w")
|
||||
.refine(
|
||||
(val) => {
|
||||
const numericPart = val.slice(0, -1);
|
||||
return parseInt(numericPart, 10) >= 1;
|
||||
},
|
||||
{ message: "Duration value must be at least 1" }
|
||||
)
|
||||
.optional()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
|
||||
@@ -17,5 +17,6 @@ export const sanitizedOrganizationSchema = OrganizationsSchema.pick({
|
||||
shouldUseNewPrivilegeSystem: true,
|
||||
privilegeUpgradeInitiatedByUsername: true,
|
||||
privilegeUpgradeInitiatedAt: true,
|
||||
bypassOrgAuthEnabled: true
|
||||
bypassOrgAuthEnabled: true,
|
||||
userTokenExpiration: true
|
||||
});
|
||||
|
||||
@@ -350,7 +350,8 @@ export const orgServiceFactory = ({
|
||||
enforceMfa,
|
||||
selectedMfaMethod,
|
||||
allowSecretSharingOutsideOrganization,
|
||||
bypassOrgAuthEnabled
|
||||
bypassOrgAuthEnabled,
|
||||
userTokenExpiration
|
||||
}
|
||||
}: TUpdateOrgDTO) => {
|
||||
const appCfg = getConfig();
|
||||
@@ -451,7 +452,8 @@ export const orgServiceFactory = ({
|
||||
enforceMfa,
|
||||
selectedMfaMethod,
|
||||
allowSecretSharingOutsideOrganization,
|
||||
bypassOrgAuthEnabled
|
||||
bypassOrgAuthEnabled,
|
||||
userTokenExpiration
|
||||
});
|
||||
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
|
||||
return org;
|
||||
|
||||
@@ -74,6 +74,7 @@ export type TUpdateOrgDTO = {
|
||||
selectedMfaMethod: MfaMethod;
|
||||
allowSecretSharingOutsideOrganization: boolean;
|
||||
bypassOrgAuthEnabled: boolean;
|
||||
userTokenExpiration: string;
|
||||
}>;
|
||||
} & TOrgPermission;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user