mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 07:26:45 +00:00
fix: review comments
This commit is contained in:
@@ -14,44 +14,35 @@ export const scimDALFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
const findExpiringTokens = async (tx?: Knex, batchSize = 500, offset = 0): Promise<TExpiringScimToken[]> => {
|
const findExpiringTokens = async (tx?: Knex, batchSize = 500, offset = 0): Promise<TExpiringScimToken[]> => {
|
||||||
try {
|
try {
|
||||||
const conn = tx || db.replicaNode();
|
const batch = await (tx || db.replicaNode())(TableName.ScimToken)
|
||||||
|
.leftJoin(TableName.Organization, `${TableName.Organization}.id`, `${TableName.ScimToken}.orgId`)
|
||||||
const batch = await conn(TableName.ScimToken)
|
.leftJoin(TableName.Membership, `${TableName.Membership}.scopeOrgId`, `${TableName.ScimToken}.orgId`)
|
||||||
.join(TableName.Organization, `${TableName.Organization}.id`, `${TableName.ScimToken}.orgId`)
|
.leftJoin(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`)
|
||||||
|
.leftJoin(TableName.Users, `${TableName.Users}.id`, `${TableName.Membership}.actorUserId`)
|
||||||
.whereRaw(
|
.whereRaw(
|
||||||
`
|
`
|
||||||
(${TableName.ScimToken}."ttlDays" > 0 AND
|
(${TableName.ScimToken}."ttlDays" > 0 AND
|
||||||
(${TableName.ScimToken}."createdAt" + INTERVAL '1 day' * ${TableName.ScimToken}."ttlDays") < NOW() + INTERVAL '1 day' AND
|
(${TableName.ScimToken}."createdAt" + INTERVAL '1 day' * ${TableName.ScimToken}."ttlDays") < NOW() + INTERVAL '7 days' AND
|
||||||
(${TableName.ScimToken}."createdAt" + INTERVAL '1 day' * ${TableName.ScimToken}."ttlDays") > NOW())
|
(${TableName.ScimToken}."createdAt" + INTERVAL '1 day' * ${TableName.ScimToken}."ttlDays") > NOW())
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
.where(`${TableName.ScimToken}.expiryNotificationSent`, false)
|
.where(`${TableName.ScimToken}.expiryNotificationSent`, false)
|
||||||
.select<TExpiringScimToken[]>(
|
.where(`${TableName.Membership}.scope`, AccessScope.Organization)
|
||||||
conn.ref("id").withSchema(TableName.ScimToken),
|
.where(`${TableName.MembershipRole}.role`, OrgMembershipRole.Admin)
|
||||||
conn.ref("ttlDays").withSchema(TableName.ScimToken),
|
.whereNot(`${TableName.Membership}.status`, OrgMembershipStatus.Invited)
|
||||||
conn.ref("description").withSchema(TableName.ScimToken),
|
.whereNotNull(`${TableName.Membership}.actorUserId`)
|
||||||
conn.ref("orgId").withSchema(TableName.ScimToken),
|
.where(`${TableName.Users}.isGhost`, false)
|
||||||
conn.ref("createdAt").withSchema(TableName.ScimToken),
|
.whereNotNull(`${TableName.Users}.email`)
|
||||||
conn.ref("name").withSchema(TableName.Organization).as("orgName"),
|
.groupBy([`${TableName.ScimToken}.id`, `${TableName.Organization}.name`])
|
||||||
conn.raw(`
|
.select<TExpiringScimToken[]>([
|
||||||
COALESCE(
|
db.ref("id").withSchema(TableName.ScimToken),
|
||||||
(
|
db.ref("ttlDays").withSchema(TableName.ScimToken),
|
||||||
SELECT array_agg(${TableName.Users}.email)
|
db.ref("description").withSchema(TableName.ScimToken),
|
||||||
FROM ${TableName.Membership}
|
db.ref("orgId").withSchema(TableName.ScimToken),
|
||||||
JOIN ${TableName.MembershipRole} ON ${TableName.Membership}.id = ${TableName.MembershipRole}."membershipId"
|
db.ref("createdAt").withSchema(TableName.ScimToken),
|
||||||
JOIN ${TableName.Users} ON ${TableName.Membership}."actorUserId" = ${TableName.Users}.id
|
db.ref("name").withSchema(TableName.Organization).as("orgName"),
|
||||||
WHERE ${TableName.Membership}."scopeOrgId" = ${TableName.ScimToken}."orgId"
|
db.raw(`array_agg(${TableName.Users}."email") as "adminEmails"`)
|
||||||
AND ${TableName.Membership}.scope = '${AccessScope.Organization}'
|
])
|
||||||
AND ${TableName.MembershipRole}.role = '${OrgMembershipRole.Admin}'
|
|
||||||
AND ${TableName.Membership}.status != '${OrgMembershipStatus.Invited}'
|
|
||||||
AND ${TableName.Membership}."actorUserId" IS NOT NULL
|
|
||||||
AND ${TableName.Users}."isGhost" = false
|
|
||||||
AND ${TableName.Users}.email IS NOT NULL
|
|
||||||
),
|
|
||||||
ARRAY[]::text[]
|
|
||||||
) as "adminEmails"
|
|
||||||
`)
|
|
||||||
)
|
|
||||||
.limit(batchSize)
|
.limit(batchSize)
|
||||||
.offset(offset);
|
.offset(offset);
|
||||||
|
|
||||||
|
|||||||
@@ -1266,6 +1266,9 @@ export const scimServiceFactory = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createdOn = new Date(token.createdAt);
|
||||||
|
const expiringOn = new Date(createdOn.getTime() + Number(token.ttlDays) * 86400 * 1000);
|
||||||
|
|
||||||
await smtpService.sendMail({
|
await smtpService.sendMail({
|
||||||
recipients: token.adminEmails,
|
recipients: token.adminEmails,
|
||||||
subjectLine: "SCIM Token Expiry Notice",
|
subjectLine: "SCIM Token Expiry Notice",
|
||||||
@@ -1273,7 +1276,9 @@ export const scimServiceFactory = ({
|
|||||||
substitutions: {
|
substitutions: {
|
||||||
tokenDescription: token.description,
|
tokenDescription: token.description,
|
||||||
orgName: token.orgName,
|
orgName: token.orgName,
|
||||||
url: `${appCfg.SITE_URL}/organizations/${token.orgId}/settings?selectedTab=provisioning-settings`
|
url: `${appCfg.SITE_URL}/organizations/${token.orgId}/settings?selectedTab=provisioning-settings`,
|
||||||
|
createdOn,
|
||||||
|
expiringOn
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
|||||||
interface ScimTokenExpiryNoticeTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface ScimTokenExpiryNoticeTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
tokenDescription?: string;
|
tokenDescription?: string;
|
||||||
orgName: string;
|
orgName: string;
|
||||||
|
createdOn: Date;
|
||||||
|
expiringOn: Date;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,8 +16,20 @@ export const ScimTokenExpiryNoticeTemplate = ({
|
|||||||
tokenDescription,
|
tokenDescription,
|
||||||
siteUrl,
|
siteUrl,
|
||||||
orgName,
|
orgName,
|
||||||
url
|
url,
|
||||||
|
createdOn,
|
||||||
|
expiringOn
|
||||||
}: ScimTokenExpiryNoticeTemplateProps) => {
|
}: ScimTokenExpiryNoticeTemplateProps) => {
|
||||||
|
const formatDate = (date: Date) =>
|
||||||
|
date.toLocaleDateString("en-US", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "long",
|
||||||
|
day: "numeric"
|
||||||
|
});
|
||||||
|
|
||||||
|
const createdOnDisplay = formatDate(createdOn);
|
||||||
|
const expiringOnDisplay = formatDate(expiringOn);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseEmailWrapper title="SCIM Token Expiring Soon" preview="A SCIM token is about to expire." siteUrl={siteUrl}>
|
<BaseEmailWrapper title="SCIM Token Expiring Soon" preview="A SCIM token is about to expire." siteUrl={siteUrl}>
|
||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
@@ -30,7 +44,8 @@ export const ScimTokenExpiryNoticeTemplate = ({
|
|||||||
) : (
|
) : (
|
||||||
"One of your SCIM tokens"
|
"One of your SCIM tokens"
|
||||||
)}{" "}
|
)}{" "}
|
||||||
for the organization <strong>{orgName}</strong> will expire within 24 hours.
|
for <strong>{orgName}</strong>, created on <strong>{createdOnDisplay}</strong>, is scheduled to expire on{" "}
|
||||||
|
<strong>{expiringOnDisplay}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
If this token is still needed for your external platform sync, please create a new one before it expires to
|
If this token is still needed for your external platform sync, please create a new one before it expires to
|
||||||
@@ -50,5 +65,7 @@ ScimTokenExpiryNoticeTemplate.PreviewProps = {
|
|||||||
orgName: "Example Organization",
|
orgName: "Example Organization",
|
||||||
siteUrl: "https://infisical.com",
|
siteUrl: "https://infisical.com",
|
||||||
url: "https://infisical.com",
|
url: "https://infisical.com",
|
||||||
tokenDescription: "Example SCIM Token"
|
tokenDescription: "Example SCIM Token",
|
||||||
|
createdOn: new Date("2025-11-27T00:00:00Z"),
|
||||||
|
expiringOn: new Date("2025-12-27T00:00:00Z")
|
||||||
} as ScimTokenExpiryNoticeTemplateProps;
|
} as ScimTokenExpiryNoticeTemplateProps;
|
||||||
|
|||||||
Reference in New Issue
Block a user