Skip to content

Subhajeetch/Animekun-db-cf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


animekun


Discord server Last commit.
Node.js Cloudflare Workers Cloudflare D1 bcryptjs jose axios


Animekun DB CF

About

Animekun-db-cf is a Cloudflare Workers backend API for @Subhajeetch/Animekun-frontend , providing user authentication, profile management, and password recovery functionality powered by Cloudflare D1 database.

Important

This project is divided into three repositories:

  1. Frontend@Subhajeetch/Animekun-frontend
  2. Backend@Subhajeetch/Animekun-backend
  3. Database – Cloudflare D1 @Subhajeetch/Animekun-db-cf (You are currently viewing this repository)

Table of Contents

Quick Start

Prerequisites

  • Node.js 18.x or higher
  • Wrangler CLI (npm install -g wrangler)
  • Cloudflare account with D1 database setup

Installation

  1. Clone the repository:
git clone https://github.com/Subhajeetch/animekun-db-cf
cd animekun-db-cf
  1. Install dependencies:
npm install
  1. Configure wrangler.toml using wrangler.toml.example:

    • Update database_id with your Cloudflare D1 database ID
  2. Set up environment variables by creating a mine.env.js file: example file: mine.env.js.example

    const env = {
      BREVO_API_KEY: "your_brevo_api_key_here",
      SECRET_KEY: "your_secret_key_here",
      REFRESH_SECRET_KEY: "your_refresh_secret_key_here",
      SENDER_EMAIL: "your_sender_email@example.com",
      ALLOWED_ORIGINS: [
        "http://localhost:3000",
        "http://localhost:5173",
        "https://yourdomain.com",
      ],
    };
    
    export default env;

    Environment Variables:

    • BREVO_API_KEY - API key from Brevo for email functionality
    • SECRET_KEY - Secret key for JWT token signing
    • REFRESH_SECRET_KEY - Secret key for refresh token signing
    • SENDER_EMAIL - Email address for sending OTP and notifications (must be verified on Brevo.com)
    • ALLOWED_ORIGINS - Array of allowed CORS origins

    Getting a Brevo API Key:

    1. Go to Brevo.com
    2. Sign up or log in to your account
    3. Navigate to SettingsSMTP & API
    4. Under API Keys, click Create a new API key
    5. Give it a name (e.g., "Animekun API")
    6. Copy the API key and paste it in your mine.env.js file as BREVO_API_KEY

Development

Run the local development server:

npm start

The server will start on localhost:8787.

Production

Deploy to Cloudflare:

wrangler deploy

API Documentation

All API endpoints accept JSON request bodies and return JSON responses. The base URL for all endpoints is your Cloudflare Workers URL.

Response Format

Successful responses:

{
  "success": true,
  "data": {}
}

Error responses:

{
  "success": false,
  "message": "Error description"
}

Authentication Endpoints

POST Sign Up

Create a new user account.

Route Schema (URL)

/sign-up

Body Parameters

Parameter Type Description Required? Default
userName string Unique username for the account (case-insensitive, minimum 4 characters). Yes --
displayName string Display name for the user profile. Yes --
email string User email address (must be unique and valid email format). Yes --
password string User password (will be hashed using bcryptjs). Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/sign-up", {
      userName: "animefan123",
      displayName: "Anime Fan",
      email: "fan@example.com",
      password: "securePassword123",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  message: "User created successfully",
  accessToken: string,
  refreshToken: string,
  user: {
    userId: number,
    userName: string,
    displayName: string,
    email: string
  }
}

Error Responses:

  • 400 - Missing required fields
  • 409 - Username or email already exists

POST Login

Authenticate user with username/email and password.

Route Schema (URL)

/login

Body Parameters

Parameter Type Description Required? Default
identifier string Username or email address (case-insensitive). Yes --
password string User password. Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/login", {
      identifier: "animefan123",
      password: "securePassword123",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  message: "Login successful",
  accessToken: string,
  refreshToken: string,
  user: {
    userId: number,
    userName: string,
    email: string
  }
}

Error Responses:

  • 400 - Missing credentials
  • 401 - Invalid username/email or password

User Profile Endpoints

POST Check Username

Validate if a username is available.

Route Schema (URL)

/check-username

Body Parameters

Parameter Type Description Required? Default
userName string Username to check (case-insensitive, minimum 4 characters). Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/check-username", {
      userName: "newusername",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200 - Available):

{
  success: true,
  isUsernameExist: false,
  message: "Great! Username is unique."
}

Success (409 - Already Taken):

{
  success: false,
  isUsernameExist: true,
  message: "This username is taken. Sad!"
}

Error Responses:

  • 400 - Username is required or less than 4 characters
  • 409 - Username already exists

POST Get User

Retrieve authenticated user information using access or refresh token.

Route Schema (URL)

/get-user

Body Parameters

Parameter Type Description Required? Default
accessToken string JWT access token (optional, used first if available). No --
refreshToken string JWT refresh token (optional, used if access token is invalid or expired). No --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/get-user", {
      accessToken: "your_access_token_here",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  user: {
    userId: number,
    userName: string,
    displayName: string,
    email: string,
    role: string,
    joinedDate: number,
    profilePicture: string,
    coverPicture: string,
    bio: string,
    pronouns: string,
    watchHours: number,
    watchedAnimes: number,
    activityStatus: string
  },
  newAccessToken: string // Only if refreshed
}

Error Responses:

  • 400 - Missing both accessToken and refreshToken
  • 401 - Not authenticated, invalid or expired tokens

POST Get Profile

Retrieve public user profile information.

Route Schema (URL)

/get-profile

Body Parameters

Parameter Type Description Required? Default
username string Username of the profile to retrieve (case-insensitive). Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/get-profile", {
      username: "animefan123",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  user: {
    userId: number,
    userName: string,
    displayName: string,
    email: string,
    profilePicture: string,
    coverPicture: string,
    coverColor: string,
    bio: string,
    pronouns: string,
    note: string,
    joinedDate: number,
    lastLogin: number,
    watchHours: number,
    watchedAnimes: number,
    activityStatus: string
  }
}

Error Responses:

  • 400 - Username not provided
  • 404 - User not found

Password Recovery Endpoints

POST Find User (Forgot Password)

Initiate password recovery by finding the user.

Route Schema (URL)

/find-user-fpass

Body Parameters

Parameter Type Description Required? Default
username string Username of the account (case-insensitive). Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/find-user-fpass", {
      username: "animefan123",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  user: {
    username: string,
    profilePicture: string,
    firstHalfEmail: string,
    secondHalfEmail: string
  },
  accessToken: string
}

Error Responses:

  • 404 - User not found
  • 500 - Internal server error

POST Verify Email (Send OTP)

Send OTP to user's registered email for password reset.

Route Schema (URL)

/verify-email-fpass

Body Parameters

Parameter Type Description Required? Default
username string Username (case-insensitive). Yes --
email string Email address (must match registered email). Yes --
accessToken string JWT access token from find-user-fpass endpoint. Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/verify-email-fpass", {
      username: "animefan123",
      email: "fan@example.com",
      accessToken: "your_access_token",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  message: "OTP sent to your email"
}

Error Responses:

  • 400 - Missing required fields
  • 403 - Email does not match registered email
  • 404 - User not found
  • 500 - Failed to send OTP

Note: OTP is valid for 30 minutes after generation.

POST Verify OTP

Verify the OTP sent to user's email.

Route Schema (URL)

/verify-otp-fpass

Body Parameters

Parameter Type Description Required? Default
accessToken string JWT access token from find-user-fpass endpoint. Yes --
otp string 6-digit OTP sent to email (case-sensitive). Yes --
username string Username (case-insensitive). Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/verify-otp-fpass", {
      accessToken: "your_access_token",
      otp: "123456",
      username: "animefan123",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  message: "OTP verified successfully"
}

Error Responses:

  • 400 - Missing required fields, incorrect OTP, or OTP expired
  • 401 - Unauthorized (token doesn't match user)
  • 500 - Internal server error

POST Change Password

Change user password after OTP verification.

Route Schema (URL)

/change-pass-fpass

Body Parameters

Parameter Type Description Required? Default
accessToken string JWT access token from find-user-fpass endpoint. Yes --
username string Username (case-insensitive). Yes --
newPassword string New password (cannot be same as old password). Yes --

Request Sample

import axios from "axios";

const data = async () => {
  try {
    const { data } = await axios.post("/change-pass-fpass", {
      accessToken: "your_access_token",
      username: "animefan123",
      newPassword: "newSecurePassword456",
    });
    return data;
  } catch (err) {
    throw new Error(err.message);
  }
};

console.log(data);

Response Schema

Success (200):

{
  success: true,
  message: "Password changed successfully"
}

Error Responses:

  • 400 - Missing required fields, new password is same as old password, or password change cooldown not elapsed
  • 401 - Unauthorized
  • 404 - User not found
  • 500 - Internal server error

Cooldown: Password can only be changed once every 15 days.


Error Handling

The API returns standard HTTP status codes:

  • 200 - Success
  • 400 - Bad request (missing or invalid parameters)
  • 401 - Unauthorized (authentication failed)
  • 403 - Forbidden (insufficient permissions)
  • 404 - Not found (resource doesn't exist)
  • 409 - Conflict (duplicate username/email)
  • 500 - Internal server error

All error responses include a message field with details about the error.


Security

Token System

The API uses JWT tokens for authentication:

  • Access Token - Short-lived token for API requests
  • Refresh Token - Long-lived token for obtaining new access tokens

Password Security

  • Passwords are hashed using bcryptjs (bcrypt algorithm)
  • Plaintext passwords are never stored
  • Password changes are rate-limited to once every 15 days

Email Verification

  • OTP-based email verification for password recovery
  • OTP valid for 30 minutes
  • 6-digit numeric OTP

CORS Configuration

CORS is configured via the ALLOWED_ORIGINS environment variable in .env.example. Specify a comma-separated list of allowed origins:

ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173,https://yourdomain.com

Only requests from these origins will be allowed.


Contributing

Contributions are welcome!
Please read the CONTRIBUTING.md file for setup instructions, development guidelines, and contribution details.

Support

If you like this project, consider giving it a star 🌟

Connect with me on X (Twitter): @subhajeetch
Join the Discord community: Animekun

License

This project is licensed under the MIT License - see the LICENSE file for more details.

About

Animekun-db-cf is a Cloudflare Workers backend API for Animekun app , providing user authentication, profile management, and password recovery functionality powered by Cloudflare D1 database.

Resources

License

Contributing

Stars

Watchers

Forks

Contributors