mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-03 13:26:02 +00:00
add max ttl to renew and login api responses
This commit is contained in:
@@ -3,28 +3,28 @@ import { Types } from "mongoose";
|
|||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
import {
|
import {
|
||||||
IIdentity,
|
IIdentity,
|
||||||
IIdentityTrustedIp,
|
IIdentityTrustedIp,
|
||||||
IIdentityUniversalAuthClientSecret,
|
IIdentityUniversalAuthClientSecret,
|
||||||
Identity,
|
Identity,
|
||||||
IdentityAccessToken,
|
IdentityAccessToken,
|
||||||
IdentityAuthMethod,
|
IdentityAuthMethod,
|
||||||
IdentityMembershipOrg,
|
IdentityMembershipOrg,
|
||||||
IdentityUniversalAuth,
|
IdentityUniversalAuth,
|
||||||
IdentityUniversalAuthClientSecret,
|
IdentityUniversalAuthClientSecret,
|
||||||
} from "../../models";
|
} from "../../models";
|
||||||
import { createToken } from "../../helpers/auth";
|
import { createToken } from "../../helpers/auth";
|
||||||
import { AuthTokenType } from "../../variables";
|
import { AuthTokenType } from "../../variables";
|
||||||
import {
|
import {
|
||||||
BadRequestError,
|
BadRequestError,
|
||||||
ForbiddenRequestError,
|
ForbiddenRequestError,
|
||||||
ResourceNotFoundError,
|
ResourceNotFoundError,
|
||||||
UnauthorizedRequestError
|
UnauthorizedRequestError
|
||||||
} from "../../utils/errors";
|
} from "../../utils/errors";
|
||||||
import {
|
import {
|
||||||
getAuthSecret,
|
getAuthSecret,
|
||||||
getSaltRounds
|
getSaltRounds
|
||||||
} from "../../config";
|
} from "../../config";
|
||||||
import { ActorType, EventType, IRole } from "../../ee/models";
|
import { ActorType, EventType, IRole } from "../../ee/models";
|
||||||
import { validateRequest } from "../../helpers/validation";
|
import { validateRequest } from "../../helpers/validation";
|
||||||
@@ -32,12 +32,12 @@ import * as reqValidator from "../../validation/auth";
|
|||||||
import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr } from "../../utils/ip";
|
import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr } from "../../utils/ip";
|
||||||
import { getUserAgentType } from "../../utils/posthog";
|
import { getUserAgentType } from "../../utils/posthog";
|
||||||
import { EEAuditLogService, EELicenseService } from "../../ee/services";
|
import { EEAuditLogService, EELicenseService } from "../../ee/services";
|
||||||
import {
|
import {
|
||||||
OrgPermissionActions,
|
OrgPermissionActions,
|
||||||
OrgPermissionSubjects,
|
OrgPermissionSubjects,
|
||||||
getAuthDataOrgPermissions,
|
getAuthDataOrgPermissions,
|
||||||
getOrgRolePermissions,
|
getOrgRolePermissions,
|
||||||
isAtLeastAsPrivilegedOrg
|
isAtLeastAsPrivilegedOrg
|
||||||
} from "../../ee/services/RoleService";
|
} from "../../ee/services/RoleService";
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ const packageUniversalAuthClientSecretData = (identityUniversalAuthClientSecret:
|
|||||||
createdAt: identityUniversalAuthClientSecret.createdAt,
|
createdAt: identityUniversalAuthClientSecret.createdAt,
|
||||||
updatedAt: identityUniversalAuthClientSecret.updatedAt
|
updatedAt: identityUniversalAuthClientSecret.updatedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renews an access token by its TTL
|
* Renews an access token by its TTL
|
||||||
* @param req
|
* @param req
|
||||||
@@ -86,9 +86,6 @@ export const renewAccessToken = async (req: Request, res: Response) => {
|
|||||||
createdAt: accessTokenCreatedAt
|
createdAt: accessTokenCreatedAt
|
||||||
} = identityAccessToken;
|
} = identityAccessToken;
|
||||||
|
|
||||||
if (accessTokenTTL === accessTokenMaxTTL) throw UnauthorizedRequestError({
|
|
||||||
message: "Failed to renew non-renewable access token"
|
|
||||||
});
|
|
||||||
|
|
||||||
// ttl check
|
// ttl check
|
||||||
if (accessTokenTTL > 0) {
|
if (accessTokenTTL > 0) {
|
||||||
@@ -141,6 +138,7 @@ export const renewAccessToken = async (req: Request, res: Response) => {
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
accessToken,
|
accessToken,
|
||||||
expiresIn: identityAccessToken.accessTokenTTL,
|
expiresIn: identityAccessToken.accessTokenTTL,
|
||||||
|
accessTokenMaxTTL: identityAccessToken.accessTokenMaxTTL,
|
||||||
tokenType: "Bearer"
|
tokenType: "Bearer"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -162,7 +160,7 @@ export const loginIdentityUniversalAuth = async (req: Request, res: Response) =>
|
|||||||
const identityUniversalAuth = await IdentityUniversalAuth.findOne({
|
const identityUniversalAuth = await IdentityUniversalAuth.findOne({
|
||||||
clientId
|
clientId
|
||||||
}).populate<{ identity: IIdentity }>("identity");
|
}).populate<{ identity: IIdentity }>("identity");
|
||||||
|
|
||||||
if (!identityUniversalAuth) throw UnauthorizedRequestError();
|
if (!identityUniversalAuth) throw UnauthorizedRequestError();
|
||||||
|
|
||||||
checkIPAgainstBlocklist({
|
checkIPAgainstBlocklist({
|
||||||
@@ -237,16 +235,16 @@ export const loginIdentityUniversalAuth = async (req: Request, res: Response) =>
|
|||||||
|
|
||||||
// increment usage count by 1
|
// increment usage count by 1
|
||||||
await IdentityUniversalAuthClientSecret
|
await IdentityUniversalAuthClientSecret
|
||||||
.findByIdAndUpdate(
|
.findByIdAndUpdate(
|
||||||
validatedClientSecretDatum._id,
|
validatedClientSecretDatum._id,
|
||||||
{
|
{
|
||||||
clientSecretLastUsedAt: new Date(),
|
clientSecretLastUsedAt: new Date(),
|
||||||
$inc: { clientSecretNumUses: 1 }
|
$inc: { clientSecretNumUses: 1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
new: true
|
new: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const identityAccessToken = await new IdentityAccessToken({
|
const identityAccessToken = await new IdentityAccessToken({
|
||||||
identity: identityUniversalAuth.identity,
|
identity: identityUniversalAuth.identity,
|
||||||
@@ -300,7 +298,8 @@ export const loginIdentityUniversalAuth = async (req: Request, res: Response) =>
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
accessToken,
|
accessToken,
|
||||||
expiresIn: identityUniversalAuth.accessTokenTTL,
|
expiresIn: identityUniversalAuth.accessTokenTTL,
|
||||||
tokenType: "Bearer"
|
accessTokenMaxTTL: identityUniversalAuth.accessTokenMaxTTL,
|
||||||
|
tokenType: "Bearer",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +327,7 @@ export const addIdentityUniversalAuth = async (req: Request, res: Response) => {
|
|||||||
if (!identityMembershipOrg) throw ResourceNotFoundError({
|
if (!identityMembershipOrg) throw ResourceNotFoundError({
|
||||||
message: `Failed to find identity with id ${identityId}`
|
message: `Failed to find identity with id ${identityId}`
|
||||||
});
|
});
|
||||||
|
|
||||||
if (identityMembershipOrg.identity?.authMethod) throw BadRequestError({
|
if (identityMembershipOrg.identity?.authMethod) throw BadRequestError({
|
||||||
message: "Failed to add universal auth to already-configured identity"
|
message: "Failed to add universal auth to already-configured identity"
|
||||||
});
|
});
|
||||||
@@ -377,7 +376,7 @@ export const addIdentityUniversalAuth = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
return extractIPDetails(accessTokenTrustedIp.ipAddress);
|
return extractIPDetails(accessTokenTrustedIp.ipAddress);
|
||||||
});
|
});
|
||||||
|
|
||||||
const identityUniversalAuth = await new IdentityUniversalAuth({
|
const identityUniversalAuth = await new IdentityUniversalAuth({
|
||||||
identity: identityMembershipOrg.identity._id,
|
identity: identityMembershipOrg.identity._id,
|
||||||
clientId: crypto.randomUUID(),
|
clientId: crypto.randomUUID(),
|
||||||
@@ -387,7 +386,7 @@ export const addIdentityUniversalAuth = async (req: Request, res: Response) => {
|
|||||||
accessTokenNumUsesLimit,
|
accessTokenNumUsesLimit,
|
||||||
accessTokenTrustedIps: reformattedAccessTokenTrustedIps,
|
accessTokenTrustedIps: reformattedAccessTokenTrustedIps,
|
||||||
}).save();
|
}).save();
|
||||||
|
|
||||||
await Identity.findByIdAndUpdate(
|
await Identity.findByIdAndUpdate(
|
||||||
identityMembershipOrg.identity._id,
|
identityMembershipOrg.identity._id,
|
||||||
{
|
{
|
||||||
@@ -439,7 +438,7 @@ export const updateIdentityUniversalAuth = async (req: Request, res: Response) =
|
|||||||
if (!identityMembershipOrg) throw ResourceNotFoundError({
|
if (!identityMembershipOrg) throw ResourceNotFoundError({
|
||||||
message: `Failed to find identity with id ${identityId}`
|
message: `Failed to find identity with id ${identityId}`
|
||||||
});
|
});
|
||||||
|
|
||||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.UNIVERSAL_AUTH) throw BadRequestError({
|
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.UNIVERSAL_AUTH) throw BadRequestError({
|
||||||
message: "Failed to add universal auth to already-configured identity"
|
message: "Failed to add universal auth to already-configured identity"
|
||||||
});
|
});
|
||||||
@@ -490,7 +489,7 @@ export const updateIdentityUniversalAuth = async (req: Request, res: Response) =
|
|||||||
return extractIPDetails(accessTokenTrustedIp.ipAddress);
|
return extractIPDetails(accessTokenTrustedIp.ipAddress);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const identityUniversalAuth = await IdentityUniversalAuth.findOneAndUpdate(
|
const identityUniversalAuth = await IdentityUniversalAuth.findOneAndUpdate(
|
||||||
{
|
{
|
||||||
identity: identityMembershipOrg.identity._id,
|
identity: identityMembershipOrg.identity._id,
|
||||||
@@ -531,7 +530,7 @@ export const getIdentityUniversalAuth = async (req: Request, res: Response) => {
|
|||||||
const {
|
const {
|
||||||
params: { identityId }
|
params: { identityId }
|
||||||
} = await validateRequest(reqValidator.GetUniversalAuthForIdentityV1, req);
|
} = await validateRequest(reqValidator.GetUniversalAuthForIdentityV1, req);
|
||||||
|
|
||||||
const identityMembershipOrg = await IdentityMembershipOrg
|
const identityMembershipOrg = await IdentityMembershipOrg
|
||||||
.findOne({
|
.findOne({
|
||||||
identity: new Types.ObjectId(identityId)
|
identity: new Types.ObjectId(identityId)
|
||||||
@@ -558,7 +557,7 @@ export const getIdentityUniversalAuth = async (req: Request, res: Response) => {
|
|||||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.UNIVERSAL_AUTH) throw BadRequestError({
|
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.UNIVERSAL_AUTH) throw BadRequestError({
|
||||||
message: "The identity does not have universal auth configured"
|
message: "The identity does not have universal auth configured"
|
||||||
});
|
});
|
||||||
|
|
||||||
const identityUniversalAuth = await IdentityUniversalAuth.findOne({
|
const identityUniversalAuth = await IdentityUniversalAuth.findOne({
|
||||||
identity: identityMembershipOrg.identity._id,
|
identity: identityMembershipOrg.identity._id,
|
||||||
});
|
});
|
||||||
@@ -625,11 +624,11 @@ export const createUniversalAuthClientSecret = async (req: Request, res: Respons
|
|||||||
|
|
||||||
const clientSecret = crypto.randomBytes(32).toString("hex");
|
const clientSecret = crypto.randomBytes(32).toString("hex");
|
||||||
const clientSecretHash = await bcrypt.hash(clientSecret, await getSaltRounds());
|
const clientSecretHash = await bcrypt.hash(clientSecret, await getSaltRounds());
|
||||||
|
|
||||||
const identityUniversalAuth = await IdentityUniversalAuth.findOne({
|
const identityUniversalAuth = await IdentityUniversalAuth.findOne({
|
||||||
identity: identityMembershipOrg.identity._id
|
identity: identityMembershipOrg.identity._id
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!identityUniversalAuth) throw ResourceNotFoundError();
|
if (!identityUniversalAuth) throw ResourceNotFoundError();
|
||||||
|
|
||||||
const identityUniversalAuthClientSecret = await new IdentityUniversalAuthClientSecret({
|
const identityUniversalAuthClientSecret = await new IdentityUniversalAuthClientSecret({
|
||||||
@@ -665,7 +664,7 @@ export const getUniversalAuthClientSecrets = async (req: Request, res: Response)
|
|||||||
const {
|
const {
|
||||||
params: { identityId }
|
params: { identityId }
|
||||||
} = await validateRequest(reqValidator.GetUniversalAuthClientSecretsV1, req);
|
} = await validateRequest(reqValidator.GetUniversalAuthClientSecretsV1, req);
|
||||||
|
|
||||||
const identityMembershipOrg = await IdentityMembershipOrg.findOne({
|
const identityMembershipOrg = await IdentityMembershipOrg.findOne({
|
||||||
identity: new Types.ObjectId(identityId)
|
identity: new Types.ObjectId(identityId)
|
||||||
}).populate<{
|
}).populate<{
|
||||||
@@ -725,7 +724,7 @@ export const revokeUniversalAuthClientSecret = async (req: Request, res: Respons
|
|||||||
const {
|
const {
|
||||||
params: { identityId, clientSecretId }
|
params: { identityId, clientSecretId }
|
||||||
} = await validateRequest(reqValidator.RevokeUniversalAuthClientSecretV1, req);
|
} = await validateRequest(reqValidator.RevokeUniversalAuthClientSecretV1, req);
|
||||||
|
|
||||||
const identityMembershipOrg = await IdentityMembershipOrg
|
const identityMembershipOrg = await IdentityMembershipOrg
|
||||||
.findOne({
|
.findOne({
|
||||||
identity: new Types.ObjectId(identityId)
|
identity: new Types.ObjectId(identityId)
|
||||||
@@ -773,7 +772,7 @@ export const revokeUniversalAuthClientSecret = async (req: Request, res: Respons
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!clientSecretData) throw ResourceNotFoundError();
|
if (!clientSecretData) throw ResourceNotFoundError();
|
||||||
|
|
||||||
await EEAuditLogService.createAuditLog(
|
await EEAuditLogService.createAuditLog(
|
||||||
req.authData,
|
req.authData,
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user