Files
whatsappNucleo/server/services/baileys/auth-state.ts
josedario87 d7d399f3ab
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 3m24s
debug: Agregar logs detallados para Baileys
2025-12-02 19:21:35 -06:00

142 lines
4.4 KiB
TypeScript

/**
* PostgreSQL-based auth state for Baileys
* Stores credentials and keys in the database instead of files
*/
import type { AuthenticationCreds, SignalDataTypeMap } from '@whiskeysockets/baileys'
import * as baileys from '@whiskeysockets/baileys'
import { query } from '../../utils/database'
// Get functions from baileys module
const initAuthCreds = (baileys as any).initAuthCreds || (baileys as any).default?.initAuthCreds
const BufferJSON = (baileys as any).BufferJSON || (baileys as any).default?.BufferJSON
const proto = (baileys as any).proto || (baileys as any).default?.proto
// Debug: Log what we got
console.log('[AuthState] initAuthCreds:', typeof initAuthCreds)
console.log('[AuthState] BufferJSON:', typeof BufferJSON)
console.log('[AuthState] proto:', typeof proto)
export interface PostgresAuthState {
state: {
creds: AuthenticationCreds
keys: {
get: <T extends keyof SignalDataTypeMap>(type: T, ids: string[]) => Promise<{ [id: string]: SignalDataTypeMap[T] }>
set: (data: { [type: string]: { [id: string]: SignalDataTypeMap[keyof SignalDataTypeMap] | null } }) => Promise<void>
}
}
saveCreds: () => Promise<void>
}
export async function usePostgresAuthState(instanceId: string): Promise<PostgresAuthState> {
// Load or create credentials
const loadCreds = async (): Promise<AuthenticationCreds> => {
const result = await query<{ key_data: any }>(
'SELECT key_data FROM auth_keys WHERE instance_id = $1 AND key_type = $2 AND key_id = $3',
[instanceId, 'creds', 'default']
)
if (result.rows.length > 0 && result.rows[0].key_data) {
return JSON.parse(JSON.stringify(result.rows[0].key_data), BufferJSON.reviver)
}
return initAuthCreds()
}
// Save credentials
const saveCreds = async (creds: AuthenticationCreds): Promise<void> => {
const data = JSON.parse(JSON.stringify(creds, BufferJSON.replacer))
await query(
`INSERT INTO auth_keys (instance_id, key_type, key_id, key_data)
VALUES ($1, $2, $3, $4)
ON CONFLICT (instance_id, key_type, key_id)
DO UPDATE SET key_data = $4, updated_at = NOW()`,
[instanceId, 'creds', 'default', data]
)
}
// Load keys by type and ids
const loadKeys = async <T extends keyof SignalDataTypeMap>(
type: T,
ids: string[]
): Promise<{ [id: string]: SignalDataTypeMap[T] }> => {
const result: { [id: string]: SignalDataTypeMap[T] } = {}
if (ids.length === 0) return result
const placeholders = ids.map((_, i) => `$${i + 3}`).join(', ')
const queryResult = await query<{ key_id: string; key_data: any }>(
`SELECT key_id, key_data FROM auth_keys
WHERE instance_id = $1 AND key_type = $2 AND key_id IN (${placeholders})`,
[instanceId, type, ...ids]
)
for (const row of queryResult.rows) {
let value = JSON.parse(JSON.stringify(row.key_data), BufferJSON.reviver)
// Handle special types
if (type === 'app-state-sync-key' && value) {
value = proto.Message.AppStateSyncKeyData.fromObject(value)
}
result[row.key_id] = value
}
return result
}
// Save keys
const saveKeys = async (
data: { [type: string]: { [id: string]: SignalDataTypeMap[keyof SignalDataTypeMap] | null } }
): Promise<void> => {
for (const type in data) {
for (const id in data[type]) {
const value = data[type][id]
if (value === null) {
// Delete key
await query(
'DELETE FROM auth_keys WHERE instance_id = $1 AND key_type = $2 AND key_id = $3',
[instanceId, type, id]
)
} else {
// Upsert key
const serialized = JSON.parse(JSON.stringify(value, BufferJSON.replacer))
await query(
`INSERT INTO auth_keys (instance_id, key_type, key_id, key_data)
VALUES ($1, $2, $3, $4)
ON CONFLICT (instance_id, key_type, key_id)
DO UPDATE SET key_data = $4, updated_at = NOW()`,
[instanceId, type, id, serialized]
)
}
}
}
}
// Load initial credentials
const creds = await loadCreds()
return {
state: {
creds,
keys: {
get: loadKeys,
set: saveKeys
}
},
saveCreds: async () => {
await saveCreds(creds)
}
}
}
/**
* Clear all auth data for an instance
*/
export async function clearAuthState(instanceId: string): Promise<void> {
await query(
'DELETE FROM auth_keys WHERE instance_id = $1',
[instanceId]
)
}