/**
* Auth adapter for hyper-social-web
*
* Wraps hyper-identity's AuthManager with social-specific permission checking.
* Uses Autobase-backed IdentityRegistry for multi-writer identity consensus.
*/
import { AuthManager, IdentityRegistry, ANProto } from 'hyper-identity'
import Hyperbee from 'hyperbee'
/**
* Initialize the auth system
*
* @param {Corestore} store - Corestore instance (shared with feed/accounts storage)
* @returns {{ authManager: AuthManager, identityRegistry: IdentityRegistry }}
*/
export async function createAuth (store) {
// Separate Hyperbee for identity direct-write storage
const identityBee = new Hyperbee(store.get({ name: 'identity-db' }), {
keyEncoding: 'utf-8',
valueEncoding: 'json'
})
await identityBee.ready()
const registry = new IdentityRegistry(store, { db: identityBee })
await registry.ready()
const authManager = new AuthManager({
identityRegistry: registry,
db: identityBee,
enableSSH: false,
autoRegister: false, // Require explicit registration — no auto-create on auth
checkPermission: checkSocialPermission,
rateLimits: {
auth: { tokens: 100, refillRate: 20, refillInterval: 60 * 1000 },
api: { tokens: 1000, refillRate: 200, refillInterval: 60 * 1000 },
'identity-generate': { tokens: 5, refillRate: 1, refillInterval: 60 * 60 * 1000 }
}
})
return { authManager, identityRegistry: registry, identityBee }
}
/**
* Social permission checker — injectable into AuthManager
*
* Resources in hyper-social: 'posts', 'accounts', 'settings', '*'
*/
function checkSocialPermission (auth, action, resourceName) {
if (!auth || !auth.verified) return false
const perms = auth.permissions
if (!perms) return false
if (perms.admin) return true
if (!perms[action]) return false
if (resourceName) {
return perms.resources && (perms.resources.includes('*') || perms.resources.includes(resourceName))
}
return true
}
/**
* Extract auth from request (non-throwing)
* Returns auth object if authenticated, null if anonymous.
*/
export async function extractAuth (req, authManager) {
try {
const result = await authManager.authenticate(req)
return result || null
} catch {
return null
}
}
/**
* Require auth — throws if not authenticated
*/
export async function requireAuth (req, authManager) {
const auth = await extractAuth(req, authManager)
if (!auth) {
const err = new Error('Authentication required')
err.status = 401
throw err
}
return auth
}
export { ANProto }