- helpers puros movidos utilities->lib: slug, phone, wordStartFilter, voteEstimate (9 inversoes lib->utilities zeradas) - chaves de consent em src/lib/campaignConsentKeys.ts (client-safe); campaignInvite/campaignConsent re-exportam; onda0ConsentTexts referencia as constantes - 'server-only' em 21 loaders Payload/cache (CLI segue com --conditions=react-server) - ciclo de tipos supporterListFilters <-> supporterUi quebrado (SupporterListFilterInput estrutural; sqlFilters idem) - votePledgeData dividido: votePledgeViews (puro, client-safe) + votePledgeData (loaders, server-only) - padrao contract-module - predicados de role client-safe em src/lib/campaignRoles.ts; access/shared deriva deles (fonte unica); nav.ts para de importar o barrel campaignAccess (casts 'as CampaignUser' eliminados)
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import { createHash, randomBytes } from 'node:crypto'
|
|
|
|
import { buildWhatsAppUrl } from '@/lib/phone'
|
|
|
|
export { CAMPAIGN_INVITE_CONSENT_KEY } from '@/lib/campaignConsentKeys'
|
|
|
|
export const CAMPAIGN_INVITE_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000
|
|
|
|
export type CampaignInviteKind = 'login' | 'autopreenchimento'
|
|
|
|
export const hashCampaignInviteToken = (token: string): string =>
|
|
createHash('sha256').update(token, 'utf8').digest('hex')
|
|
|
|
export const generateCampaignInviteToken = (): {
|
|
token: string
|
|
tokenHash: string
|
|
} => {
|
|
const token = randomBytes(32).toString('base64url')
|
|
return {
|
|
token,
|
|
tokenHash: hashCampaignInviteToken(token),
|
|
}
|
|
}
|
|
|
|
export const campaignInviteExpiry = (now = new Date()): Date =>
|
|
new Date(now.getTime() + CAMPAIGN_INVITE_EXPIRATION_MS)
|
|
|
|
type WhatsAppInviteInput = {
|
|
phone: string
|
|
recipientName: string
|
|
senderName: string
|
|
inviteUrl: string
|
|
kind: CampaignInviteKind
|
|
}
|
|
|
|
export const buildCampaignInviteWhatsAppLink = ({
|
|
phone,
|
|
recipientName,
|
|
senderName,
|
|
inviteUrl,
|
|
kind,
|
|
}: WhatsAppInviteInput): string => {
|
|
const action =
|
|
kind === 'login'
|
|
? 'Crie ou recupere seu acesso à plataforma'
|
|
: 'Complete e confirme seu cadastro'
|
|
const message = `Oi ${recipientName}, aqui é ${senderName} da campanha do Solla. ${action} neste link: ${inviteUrl}`
|
|
|
|
return buildWhatsAppUrl(phone, message)
|
|
}
|