mirror of
https://github.com/kind-0/nsecbunkerd.git
synced 2026-08-01 07:21:42 +00:00
BREAKING CHANGE: Admin API now uses kind 24133 instead of 24134 This release adds 11 new admin methods and ensures full NIP-46 compliance by switching from the non-standard kind 24134 to the spec-compliant 24133. ## New Admin Methods ### Key Management - `get_key` - Get details about a specific key - `delete_key` - Soft-delete a key and its tokens - `rotate_key` - Create new key and migrate permissions ### Policy Management - `get_policy` - Get policy details with rules - `delete_policy` - Soft-delete a policy ### Permission Management - `grant_permission` - Grant user access with a policy - `revoke_permission` - Revoke user's access to a key - `get_permissions` - Get user's permissions on a key ### Token Management - `get_token` - Get token details - `revoke_token` - Soft-delete a token - `validate_token` - Check if a token is valid ## NIP-46 Compliance Changed all admin communication from kind 24134 to kind 24133 (NDKKind.NostrConnect) to comply with the NIP-46 specification. Kind 24134 was never part of the official spec. ## Other Changes - Added Vitest test framework with 93 tests - Fixed TypeScript compilation errors - Updated documentation with breaking change notice - Version bump to 0.11.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
import { NDKKind, NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
|
import AdminInterface from "../index.js";
|
|
import prisma from "../../../db.js";
|
|
|
|
export default async function validateToken(admin: AdminInterface, req: NDKRpcRequest) {
|
|
const [tokenString] = req.params as [string];
|
|
|
|
if (!tokenString) throw new Error("Invalid params: token required");
|
|
|
|
// Parse token string - may include npub# prefix
|
|
let tokenValue = tokenString;
|
|
if (tokenString.includes('#')) {
|
|
tokenValue = tokenString.split('#')[1];
|
|
}
|
|
|
|
const token = await prisma.token.findUnique({
|
|
where: { token: tokenValue },
|
|
});
|
|
|
|
if (!token) {
|
|
const result = JSON.stringify({
|
|
valid: false,
|
|
reason: "Token not found",
|
|
});
|
|
return admin.rpc.sendResponse(req.id, req.pubkey, result, NDKKind.NostrConnect);
|
|
}
|
|
|
|
// Check if token is revoked (soft deleted)
|
|
if (token.deletedAt) {
|
|
const result = JSON.stringify({
|
|
valid: false,
|
|
reason: "Token has been revoked",
|
|
});
|
|
return admin.rpc.sendResponse(req.id, req.pubkey, result, NDKKind.NostrConnect);
|
|
}
|
|
|
|
// Check if token is expired
|
|
if (token.expiresAt && token.expiresAt < new Date()) {
|
|
const result = JSON.stringify({
|
|
valid: false,
|
|
reason: "Token has expired",
|
|
});
|
|
return admin.rpc.sendResponse(req.id, req.pubkey, result, NDKKind.NostrConnect);
|
|
}
|
|
|
|
// Token is valid
|
|
const result = JSON.stringify({
|
|
valid: true,
|
|
key_name: token.keyName,
|
|
client_name: token.clientName,
|
|
expires_at: token.expiresAt,
|
|
redeemed: token.redeemedAt !== null,
|
|
});
|
|
|
|
return admin.rpc.sendResponse(req.id, req.pubkey, result, NDKKind.NostrConnect);
|
|
}
|