Skip to content

Repository files navigation

Inkline Blog API

Backend API for Inkline, a full-stack publishing platform. It provides authentication, post publishing, nested comments, moderation, platform statistics, and administrator account management.

Stack

  • Node.js 20.9+
  • Express 5 and TypeScript
  • PostgreSQL
  • Prisma 7 with the PostgreSQL adapter
  • Better Auth (email/password and Google OAuth)
  • Nodemailer for verification and password-reset email

The API runs at http://localhost:3000 by default and supports both maintained local frontends:

Frontend Local URL
Angular http://localhost:4200
Next.js http://localhost:4000

Features

  • Email/password registration and sign-in
  • Google OAuth
  • Email verification and password reset
  • Cookie-based sessions and role-based authorization
  • USER and ADMIN roles
  • ACTIVE and SUSPENDED account states
  • Post creation, editing, deletion, drafts, publishing, archiving, tags, featured posts, search, sorting, and pagination
  • View counting and platform statistics
  • Nested comments with edit/delete support
  • Administrator comment approval/rejection
  • Administrator user search, role changes, suspension, and reactivation
  • Immediate session revocation for suspended accounts
  • Protection against self-suspension and removal of the final active administrator

Project structure

prisma/
  migrations/             Database migrations
  schema/                 Split Prisma schema files
src/
  helpers/                Pagination and sorting helpers
  lib/                    Better Auth and Prisma configuration
  middlewares/            Authentication and error handling
  modules/
    comment/              Comment API
    post/                 Post API
    user/                 Admin user-management API
  scripts/admin.ts        Development admin seeder
  app.ts                  Express application
  server.ts               Database check and HTTP server startup

Environment variables

Create .env in the project root:

PORT=3000
DATABASE_URL=postgresql://postgres:your_password@localhost:5432/blog_app

BETTER_AUTH_SECRET=replace-with-a-long-random-secret
BETTER_AUTH_URL=http://localhost:3000
APP_URL=http://localhost:4200
CLIENT_URLS=http://localhost:4000,http://localhost:4200

APP_USER=your-smtp-email@example.com
APP_PASS=your-smtp-app-password

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

APP_URL is the primary frontend used in verification and password-reset links. Set it to http://localhost:4200 while developing the Angular application, or http://localhost:4000 while developing Next.js.

CLIENT_URLS is the comma-separated allowlist shared by Express CORS and Better Auth trusted origins. Keep every frontend that may call the API in this list. Origins must include the protocol and port, must not include a route, and should not have a trailing slash. Do not use a wildcard because authentication depends on credentialed cookies.

For Gmail SMTP, use an app password rather than the normal account password.

Frontend origin and authentication setup

Both local frontends can use the same API process. Configure each frontend to use http://localhost:3000 as its API/auth base URL and send cookies with protected requests. The backend enables credentialed CORS only for origins in CLIENT_URLS.

Better Auth receives OAuth callbacks on the API origin and then redirects to the absolute frontend callback URL supplied by the client. For Google OAuth local development, configure this redirect URI in Google Cloud:

http://localhost:3000/api/auth/callback/google

Also add the frontend origins you actively use as authorized JavaScript origins:

http://localhost:4200
http://localhost:4000

Restart the backend after changing .env. If a frontend is omitted from CLIENT_URLS, browser requests may fail with CORS errors or Better Auth may reject the origin. If OAuth lands on a backend /dashboard route, the frontend passed a relative callback URL; pass an absolute URL on the Angular or Next.js origin instead.

Local setup

  1. Install dependencies:

    npm install
  2. Start PostgreSQL and create the database referenced by DATABASE_URL.

  3. Apply migrations and generate the Prisma client:

    npx prisma migrate dev
    npx prisma generate
  4. Start the API:

    npm run dev

The server verifies the database connection before listening. A Prisma ECONNREFUSED error means PostgreSQL is not reachable at the host/port in DATABASE_URL.

Scripts

Command Purpose
npm run dev Run the API with TSX watch mode
npm run build Generate Prisma Client and compile TypeScript
npm start Run the compiled server from dist/
npm run seed:admin Create the development admin defined in src/scripts/admin.ts
npx prisma studio Open Prisma Studio

The current admin seed script contains development-only account values. Change them before running it outside a local environment.

API overview

All Better Auth endpoints are mounted under /api/auth/*.

Posts

Method Route Access Purpose
GET /posts Public List/search/filter/sort posts
GET /posts/stats Admin Platform statistics
GET /posts/my-posts User/Admin Current writer's posts
GET /posts/:postId Public Read a post and approved comments
POST /posts User/Admin Create a post
PATCH /posts/:postId Owner/Admin Update a post
DELETE /posts/:postId Owner/Admin Delete a post

Common GET /posts query parameters: search, tags, isFeatured, status, authorId, page, limit, sortBy, and sortOrder.

Comments

Method Route Access Purpose
GET /comments Admin List comments for moderation
GET /comments/author/:authorId Public List an author's comments
GET /comments/:commentId Public Get one comment
POST /comments User/Admin Add a comment or reply
PATCH /comments/:commentId Owner/Admin Edit a comment
DELETE /comments/:commentId Owner/Admin Delete a comment
PATCH /comments/:commentId/moderate Admin Approve or reject a comment

Users

Method Route Access Purpose
GET /users Admin Search/filter/paginate users and activity counts
PATCH /users/:userId Admin Change role or account status

GET /users accepts search, role, status, page, and limit. Update payloads may contain role: "USER" | "ADMIN" and/or status: "ACTIVE" | "SUSPENDED".

Authorization notes

  • Protected requests require the Better Auth session cookie and a verified email.
  • Ownership checks prevent writers from modifying another writer's content.
  • Only admins can view statistics, moderate comments, feature any post, and manage users.
  • Suspended accounts cannot create sessions or use protected routes.
  • CORS credentials are enabled; browser API requests must use credentials: "include" (Angular's auth/API clients must enable the equivalent credential option).

Production

npm run build
npm start

Before deployment:

  • Set BETTER_AUTH_URL to the public HTTPS API origin.
  • Set APP_URL to the primary public frontend and list every permitted public frontend in CLIENT_URLS.
  • Add the production Better Auth callback URI to the Google OAuth client.
  • Use production values for the database, auth secret, and SMTP credentials.
  • Run production migrations as part of the release process.

About

A backend blog application built with Express.js, PostgreSQL, and Prisma, featuring authentication using Better Auth with Email/Password and Google OAuth.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages