Implement company provisioning codes and session tweaks
This commit is contained in:
parent
0fb9bf59b2
commit
2cba553efa
28 changed files with 1407 additions and 534 deletions
|
|
@ -17,28 +17,6 @@ type NormalizedIdentifiers = {
|
|||
serials: string[]
|
||||
}
|
||||
|
||||
function normalizeCompanySlug(input?: string | null): string | undefined {
|
||||
if (!input) return undefined
|
||||
const trimmed = input.trim()
|
||||
if (!trimmed) return undefined
|
||||
const ascii = trimmed
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/[\u2013\u2014]/g, "-")
|
||||
const sanitized = ascii.replace(/[^\w\s-]/g, "").replace(/[_\s]+/g, "-")
|
||||
const collapsed = sanitized.replace(/-+/g, "-").toLowerCase()
|
||||
const normalized = collapsed.replace(/^-+|-+$/g, "")
|
||||
return normalized || undefined
|
||||
}
|
||||
|
||||
function getProvisioningSecret() {
|
||||
const secret = process.env["MACHINE_PROVISIONING_SECRET"]
|
||||
if (!secret) {
|
||||
throw new ConvexError("Provisionamento de máquinas não configurado")
|
||||
}
|
||||
return secret
|
||||
}
|
||||
|
||||
function getTokenTtlMs(): number {
|
||||
const raw = process.env["MACHINE_TOKEN_TTL_MS"]
|
||||
if (!raw) return DEFAULT_TOKEN_TTL_MS
|
||||
|
|
@ -122,23 +100,6 @@ function hashToken(token: string) {
|
|||
return toHex(sha256(token))
|
||||
}
|
||||
|
||||
async function ensureCompany(
|
||||
ctx: MutationCtx,
|
||||
tenantId: string,
|
||||
companySlug?: string
|
||||
): Promise<{ companyId?: Id<"companies">; companySlug?: string }> {
|
||||
const normalized = normalizeCompanySlug(companySlug)
|
||||
if (!normalized) return {}
|
||||
const company = await ctx.db
|
||||
.query("companies")
|
||||
.withIndex("by_tenant_slug", (q: any) => q.eq("tenantId", tenantId).eq("slug", normalized))
|
||||
.unique()
|
||||
if (!company) {
|
||||
throw new ConvexError("Empresa não encontrada para o tenant informado")
|
||||
}
|
||||
return { companyId: company._id, companySlug: company.slug }
|
||||
}
|
||||
|
||||
async function getActiveToken(
|
||||
ctx: MutationCtx,
|
||||
tokenValue: string
|
||||
|
|
@ -332,9 +293,7 @@ async function evaluatePostureAndMaybeRaise(
|
|||
|
||||
export const register = mutation({
|
||||
args: {
|
||||
provisioningSecret: v.string(),
|
||||
tenantId: v.optional(v.string()),
|
||||
companySlug: v.optional(v.string()),
|
||||
provisioningCode: v.string(),
|
||||
hostname: v.string(),
|
||||
os: v.object({
|
||||
name: v.string(),
|
||||
|
|
@ -347,16 +306,21 @@ export const register = mutation({
|
|||
registeredBy: v.optional(v.string()),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const secret = getProvisioningSecret()
|
||||
if (args.provisioningSecret !== secret) {
|
||||
const normalizedCode = args.provisioningCode.trim().toLowerCase()
|
||||
const companyRecord = await ctx.db
|
||||
.query("companies")
|
||||
.withIndex("by_provisioning_code", (q) => q.eq("provisioningCode", normalizedCode))
|
||||
.unique()
|
||||
|
||||
if (!companyRecord) {
|
||||
throw new ConvexError("Código de provisionamento inválido")
|
||||
}
|
||||
|
||||
const tenantId = args.tenantId ?? DEFAULT_TENANT_ID
|
||||
const normalizedCompanySlug = normalizeCompanySlug(args.companySlug)
|
||||
const tenantId = companyRecord.tenantId ?? DEFAULT_TENANT_ID
|
||||
const companyId = companyRecord._id
|
||||
const companySlug = companyRecord.slug
|
||||
const identifiers = normalizeIdentifiers(args.macAddresses, args.serialNumbers)
|
||||
const fingerprint = computeFingerprint(tenantId, normalizedCompanySlug, args.hostname, identifiers)
|
||||
const { companyId, companySlug } = await ensureCompany(ctx, tenantId, normalizedCompanySlug)
|
||||
const fingerprint = computeFingerprint(tenantId, companySlug, args.hostname, identifiers)
|
||||
const now = Date.now()
|
||||
const metadataPatch = args.metadata && typeof args.metadata === "object" ? (args.metadata as Record<string, unknown>) : undefined
|
||||
|
||||
|
|
@ -469,9 +433,7 @@ export const register = mutation({
|
|||
|
||||
export const upsertInventory = mutation({
|
||||
args: {
|
||||
provisioningSecret: v.string(),
|
||||
tenantId: v.optional(v.string()),
|
||||
companySlug: v.optional(v.string()),
|
||||
provisioningCode: v.string(),
|
||||
hostname: v.string(),
|
||||
os: v.object({
|
||||
name: v.string(),
|
||||
|
|
@ -485,16 +447,21 @@ export const upsertInventory = mutation({
|
|||
registeredBy: v.optional(v.string()),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const secret = getProvisioningSecret()
|
||||
if (args.provisioningSecret !== secret) {
|
||||
const normalizedCode = args.provisioningCode.trim().toLowerCase()
|
||||
const companyRecord = await ctx.db
|
||||
.query("companies")
|
||||
.withIndex("by_provisioning_code", (q) => q.eq("provisioningCode", normalizedCode))
|
||||
.unique()
|
||||
|
||||
if (!companyRecord) {
|
||||
throw new ConvexError("Código de provisionamento inválido")
|
||||
}
|
||||
|
||||
const tenantId = args.tenantId ?? DEFAULT_TENANT_ID
|
||||
const normalizedCompanySlug = normalizeCompanySlug(args.companySlug)
|
||||
const tenantId = companyRecord.tenantId ?? DEFAULT_TENANT_ID
|
||||
const companyId = companyRecord._id
|
||||
const companySlug = companyRecord.slug
|
||||
const identifiers = normalizeIdentifiers(args.macAddresses, args.serialNumbers)
|
||||
const fingerprint = computeFingerprint(tenantId, normalizedCompanySlug, args.hostname, identifiers)
|
||||
const { companyId, companySlug } = await ensureCompany(ctx, tenantId, normalizedCompanySlug)
|
||||
const fingerprint = computeFingerprint(tenantId, companySlug, args.hostname, identifiers)
|
||||
const now = Date.now()
|
||||
|
||||
const metadataPatch: Record<string, unknown> = {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue