mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
chore: switch storage to D1 (test branch)
This commit is contained in:
@@ -14,7 +14,7 @@ function jwtSecretUnsafeReason(env: Env): 'missing' | 'default' | 'too_short' |
|
||||
|
||||
// POST /api/accounts/register (only used from setup page, not client)
|
||||
export async function handleRegister(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
// Enforce safe JWT_SECRET before allowing first registration.
|
||||
const unsafe = jwtSecretUnsafeReason(env);
|
||||
@@ -96,7 +96,7 @@ export async function handleRegister(request: Request, env: Env): Promise<Respon
|
||||
|
||||
// GET /api/accounts/profile
|
||||
export async function handleGetProfile(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const user = await storage.getUserById(userId);
|
||||
|
||||
if (!user) {
|
||||
@@ -132,7 +132,7 @@ export async function handleGetProfile(request: Request, env: Env, userId: strin
|
||||
|
||||
// PUT /api/accounts/profile
|
||||
export async function handleUpdateProfile(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const user = await storage.getUserById(userId);
|
||||
|
||||
if (!user) {
|
||||
@@ -158,7 +158,7 @@ export async function handleUpdateProfile(request: Request, env: Env, userId: st
|
||||
|
||||
// POST /api/accounts/keys
|
||||
export async function handleSetKeys(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const user = await storage.getUserById(userId);
|
||||
|
||||
if (!user) {
|
||||
@@ -189,7 +189,7 @@ export async function handleSetKeys(request: Request, env: Env, userId: string):
|
||||
|
||||
// GET /api/accounts/revision-date
|
||||
export async function handleGetRevisionDate(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const revisionDate = await storage.getRevisionDate(userId);
|
||||
|
||||
// Return as milliseconds timestamp (Bitwarden format)
|
||||
@@ -199,7 +199,7 @@ export async function handleGetRevisionDate(request: Request, env: Env, userId:
|
||||
|
||||
// POST /api/accounts/verify-password
|
||||
export async function handleVerifyPassword(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const user = await storage.getUserById(userId);
|
||||
|
||||
if (!user) {
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function handleCreateAttachment(
|
||||
userId: string,
|
||||
cipherId: string
|
||||
): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
// Verify cipher exists and belongs to user
|
||||
const cipher = await storage.getCipher(cipherId);
|
||||
@@ -96,7 +96,7 @@ export async function handleUploadAttachment(
|
||||
cipherId: string,
|
||||
attachmentId: string
|
||||
): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
// Verify cipher exists and belongs to user
|
||||
const cipher = await storage.getCipher(cipherId);
|
||||
@@ -169,7 +169,7 @@ export async function handleGetAttachment(
|
||||
cipherId: string,
|
||||
attachmentId: string
|
||||
): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
// Verify cipher exists and belongs to user
|
||||
const cipher = await storage.getCipher(cipherId);
|
||||
@@ -227,7 +227,8 @@ export async function handlePublicDownloadAttachment(
|
||||
return errorResponse('Token mismatch', 401);
|
||||
}
|
||||
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
|
||||
// Verify attachment exists
|
||||
const attachment = await storage.getAttachment(attachmentId);
|
||||
@@ -262,7 +263,7 @@ export async function handleDeleteAttachment(
|
||||
cipherId: string,
|
||||
attachmentId: string
|
||||
): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
// Verify cipher exists and belongs to user
|
||||
const cipher = await storage.getCipher(cipherId);
|
||||
@@ -348,7 +349,7 @@ export async function deleteAllAttachmentsForCipher(
|
||||
env: Env,
|
||||
cipherId: string
|
||||
): Promise<void> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const attachments = await storage.getAttachmentsByCipher(cipherId);
|
||||
|
||||
for (const attachment of attachments) {
|
||||
|
||||
@@ -57,7 +57,7 @@ function cipherToResponse(cipher: Cipher, attachments: Attachment[] = []): Ciphe
|
||||
|
||||
// GET /api/ciphers
|
||||
export async function handleGetCiphers(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const ciphers = await storage.getAllCiphers(userId);
|
||||
|
||||
// Filter out soft-deleted ciphers unless specifically requested
|
||||
@@ -84,7 +84,7 @@ export async function handleGetCiphers(request: Request, env: Env, userId: strin
|
||||
|
||||
// GET /api/ciphers/:id
|
||||
export async function handleGetCipher(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const cipher = await storage.getCipher(id);
|
||||
|
||||
if (!cipher || cipher.userId !== userId) {
|
||||
@@ -97,7 +97,7 @@ export async function handleGetCipher(request: Request, env: Env, userId: string
|
||||
|
||||
// POST /api/ciphers
|
||||
export async function handleCreateCipher(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
let body: any;
|
||||
try {
|
||||
@@ -141,7 +141,7 @@ export async function handleCreateCipher(request: Request, env: Env, userId: str
|
||||
|
||||
// PUT /api/ciphers/:id
|
||||
export async function handleUpdateCipher(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const existingCipher = await storage.getCipher(id);
|
||||
|
||||
if (!existingCipher || existingCipher.userId !== userId) {
|
||||
@@ -186,7 +186,7 @@ export async function handleUpdateCipher(request: Request, env: Env, userId: str
|
||||
|
||||
// DELETE /api/ciphers/:id
|
||||
export async function handleDeleteCipher(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const cipher = await storage.getCipher(id);
|
||||
|
||||
if (!cipher || cipher.userId !== userId) {
|
||||
@@ -204,7 +204,7 @@ export async function handleDeleteCipher(request: Request, env: Env, userId: str
|
||||
|
||||
// DELETE /api/ciphers/:id (permanent)
|
||||
export async function handlePermanentDeleteCipher(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const cipher = await storage.getCipher(id);
|
||||
|
||||
if (!cipher || cipher.userId !== userId) {
|
||||
@@ -222,7 +222,7 @@ export async function handlePermanentDeleteCipher(request: Request, env: Env, us
|
||||
|
||||
// PUT /api/ciphers/:id/restore
|
||||
export async function handleRestoreCipher(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const cipher = await storage.getCipher(id);
|
||||
|
||||
if (!cipher || cipher.userId !== userId) {
|
||||
@@ -239,7 +239,7 @@ export async function handleRestoreCipher(request: Request, env: Env, userId: st
|
||||
|
||||
// PUT /api/ciphers/:id/partial - Update only favorite/folderId
|
||||
export async function handlePartialUpdateCipher(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const cipher = await storage.getCipher(id);
|
||||
|
||||
if (!cipher || cipher.userId !== userId) {
|
||||
@@ -269,7 +269,7 @@ export async function handlePartialUpdateCipher(request: Request, env: Env, user
|
||||
|
||||
// POST/PUT /api/ciphers/move - Bulk move to folder
|
||||
export async function handleBulkMoveCiphers(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
let body: { ids?: string[]; folderId?: string | null };
|
||||
try {
|
||||
|
||||
@@ -15,7 +15,7 @@ function folderToResponse(folder: Folder): FolderResponse {
|
||||
|
||||
// GET /api/folders
|
||||
export async function handleGetFolders(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const folders = await storage.getAllFolders(userId);
|
||||
|
||||
return jsonResponse({
|
||||
@@ -27,7 +27,7 @@ export async function handleGetFolders(request: Request, env: Env, userId: strin
|
||||
|
||||
// GET /api/folders/:id
|
||||
export async function handleGetFolder(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const folder = await storage.getFolder(id);
|
||||
|
||||
if (!folder || folder.userId !== userId) {
|
||||
@@ -39,7 +39,7 @@ export async function handleGetFolder(request: Request, env: Env, userId: string
|
||||
|
||||
// POST /api/folders
|
||||
export async function handleCreateFolder(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
let body: { name?: string };
|
||||
try {
|
||||
@@ -68,7 +68,7 @@ export async function handleCreateFolder(request: Request, env: Env, userId: str
|
||||
|
||||
// PUT /api/folders/:id
|
||||
export async function handleUpdateFolder(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const folder = await storage.getFolder(id);
|
||||
|
||||
if (!folder || folder.userId !== userId) {
|
||||
@@ -94,7 +94,7 @@ export async function handleUpdateFolder(request: Request, env: Env, userId: str
|
||||
|
||||
// DELETE /api/folders/:id
|
||||
export async function handleDeleteFolder(request: Request, env: Env, userId: string, id: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const folder = await storage.getFolder(id);
|
||||
|
||||
if (!folder || folder.userId !== userId) {
|
||||
|
||||
@@ -6,9 +6,9 @@ import { jsonResponse, errorResponse, identityErrorResponse } from '../utils/res
|
||||
|
||||
// POST /identity/connect/token
|
||||
export async function handleToken(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const auth = new AuthService(env);
|
||||
const rateLimit = new RateLimitService(env.VAULT);
|
||||
const rateLimit = new RateLimitService(env.DB);
|
||||
|
||||
let body: Record<string, string>;
|
||||
const contentType = request.headers.get('content-type') || '';
|
||||
@@ -28,7 +28,8 @@ export async function handleToken(request: Request, env: Env): Promise<Response>
|
||||
const passwordHash = body.password;
|
||||
|
||||
if (!email || !passwordHash) {
|
||||
return errorResponse('Email and password are required', 400);
|
||||
// Bitwarden clients expect OAuth-style error fields.
|
||||
return identityErrorResponse('Email and password are required', 'invalid_request', 400);
|
||||
}
|
||||
|
||||
const user = await storage.getUser(email);
|
||||
@@ -156,7 +157,7 @@ export async function handleToken(request: Request, env: Env): Promise<Response>
|
||||
|
||||
// POST /identity/accounts/prelogin
|
||||
export async function handlePrelogin(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
let body: { email?: string };
|
||||
try {
|
||||
|
||||
@@ -68,7 +68,7 @@ interface CiphersImportRequest {
|
||||
|
||||
// POST /api/ciphers/import - Bitwarden client import endpoint
|
||||
export async function handleCiphersImport(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
let importData: CiphersImportRequest;
|
||||
try {
|
||||
|
||||
@@ -15,7 +15,7 @@ function getJwtSecretState(env: Env): JwtSecretState | null {
|
||||
|
||||
// GET / - Setup page
|
||||
export async function handleSetupPage(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const disabled = await storage.isSetupDisabled();
|
||||
if (disabled) {
|
||||
return new Response(null, { status: 404 });
|
||||
@@ -33,7 +33,7 @@ export async function handleSetupPage(request: Request, env: Env): Promise<Respo
|
||||
|
||||
// GET /setup/status
|
||||
export async function handleSetupStatus(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const registered = await storage.isRegistered();
|
||||
const disabled = await storage.isSetupDisabled();
|
||||
return jsonResponse({ registered, disabled });
|
||||
@@ -41,7 +41,7 @@ export async function handleSetupStatus(request: Request, env: Env): Promise<Res
|
||||
|
||||
// POST /setup/disable
|
||||
export async function handleDisableSetup(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const registered = await storage.isRegistered();
|
||||
if (!registered) {
|
||||
return errorResponse('Registration required', 403);
|
||||
|
||||
@@ -659,7 +659,7 @@ const registerPageHTML = `<!DOCTYPE html>
|
||||
</html>`;
|
||||
|
||||
export async function handleRegisterPage(request: Request, env: Env): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
const disabled = await storage.isSetupDisabled();
|
||||
if (disabled) {
|
||||
return new Response(null, { status: 404 });
|
||||
|
||||
@@ -18,7 +18,7 @@ function formatAttachments(attachments: Attachment[]): any[] | null {
|
||||
|
||||
// GET /api/sync
|
||||
export async function handleSync(request: Request, env: Env, userId: string): Promise<Response> {
|
||||
const storage = new StorageService(env.VAULT);
|
||||
const storage = new StorageService(env.DB);
|
||||
|
||||
const user = await storage.getUserById(userId);
|
||||
if (!user) {
|
||||
|
||||
Reference in New Issue
Block a user