Skip to content

LPIX-11/strapi-security-suite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

19 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ›ก๏ธ Strapi Security Suite

The admin security plugin that takes your sessions personally.

One plugin. Auto-logout. Single-session enforcement. Token revocation. Password policy. Built for Strapi v5. Fueled by in-memory Maps and zero tolerance for stale tokens.


๐Ÿค” What Is This?

Imagine a bouncer at a nightclub. But the nightclub is your Strapi admin panel, and the bouncer has a perfect memory, never sleeps, and will physically escort your idle admins out the door after 30 minutes of doing nothing.

That's this plugin.

  ๐Ÿ” Admin logs in
   |
   |  ๐Ÿ‘€ Every request tracked (timestamp saved in memory)
   |
   |  ๐Ÿ˜ด Admin goes idle...
   |
   |  โฐ 30 minutes pass...
   |
   ๐Ÿšช BOOM. Logged out. Cookies cleared. Token dead.
         No arguments. No appeals. Just security.

โœจ Features at a Glance

Feature What It Does Vibe
โฐ Auto-Logout Kicks idle admins after configurable minutes "Use it or lose it"
๐Ÿšซ Single-Session Lock One admin = one session. Period. "No shadow clones"
๐Ÿ’€ Token Revocation Dead tokens stay dead. Instantly. "Ghosts get ghosted"
๐Ÿ”‘ Password Policy Expiry + non-reusable passwords (configurable) "Rotate or regret"
โš™๏ธ Admin UI Settings panel right inside Strapi "Click, don't code"
๐Ÿ›ก๏ธ Input Validation Server-side validation on every settings save "Trust nobody"

๐Ÿš€ Quick Start

Step 1: Install it

yarn add strapi-security-suite

Step 2: Enable it

Add this to your config/plugins.js (or .ts):

module.exports = ({ env }) => ({
  'strapi-security-suite': {
    enabled: true,
  },
});

Step 3: Restart Strapi

yarn develop

Step 4: Find it

Go to Settings โ†’ Global โ†’ Security Suite

That's it. You're done. Go get a coffee. โ˜•


๐Ÿ–ผ๏ธ The Admin Panel

Once installed, you get a beautiful settings page with two panels:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            ๐Ÿ›ก๏ธ Security & Session Settings              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                           โ”‚                           โ”‚
โ”‚  ๐Ÿ• SESSION MANAGEMENT    โ”‚  ๐Ÿ”‘ PASSWORD MANAGEMENT    โ”‚
โ”‚                           โ”‚                           โ”‚
โ”‚  Auto Logout Time: [30]  โ”‚  Password Control: [ON]   โ”‚
โ”‚  (minutes)               โ”‚                           โ”‚
โ”‚                           โ”‚  Expiry Days: [30]        โ”‚
โ”‚  Multi-Session            โ”‚                           โ”‚
โ”‚  Control: [ON]            โ”‚  Non-Reusable: [ON]       โ”‚
โ”‚                           โ”‚                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                               [ ๐Ÿ’พ Save Settings ]    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Everything is stored in the database. Change a value, hit save, it takes effect immediately. No restarts. No config files. No drama.


๐Ÿง  How It Actually Works

Here's the whole flow, explained like you're five (but a very smart five):

๐Ÿ”— The Middleware Pipeline

When any request hits your Strapi server, it passes through 5 security checkpoints (middlewares), in this exact order:

  ๐ŸŒ Incoming Request
       โ”‚
       โ–ผ
  1. ๐Ÿฃ seedUserInfos
  โ”‚    "Who are you? Let me check your JWT and load your profile"
  โ”‚
  โ–ผ
  2. ๐Ÿ” interceptRenewToken
  โ”‚    "Trying to renew your token? Let me make sure you're still welcome"
  โ”‚
  โ–ผ
  3. ๐Ÿ‘ฃ trackActivity
  โ”‚    "OK you're legit. I'm writing down the time. Don't be idle."
  โ”‚
  โ–ผ
  4. โ˜ ๏ธ rejectRevokedTokens
  โ”‚    "Wait... is your session revoked? GET OUT. Cookies deleted. Token dead."
  โ”‚
  โ–ผ
  5. ๐Ÿšซ preventMultipleSessions  (on login only)
       "Already logged in somewhere else? 409 Conflict. One session only."

โฑ๏ธ The Auto-Logout Watcher

Running in the background, checking every 5 seconds:

  ๐Ÿ”„ Every 5 seconds:
     โ”‚
     โ”‚  ๐Ÿ” Check each active session in memory
     โ”‚  ๐Ÿ• Compare last activity timestamp vs. configured timeout
     โ”‚
     โ”‚  ๐Ÿ˜ด Idle too long?
     โ”‚     โ”‚
     โ”‚     YES โ†’ Add email to revoked set
     โ”‚     โ”‚     โ†’ Delete session from activity map
     โ”‚     โ”‚     โ†’ Log it: "Auto-logged out admin X after Y seconds"
     โ”‚     โ”‚
     โ”‚     NO  โ†’ Carry on, you're fine ๐Ÿ‘

๐Ÿ–ฅ๏ธ The Frontend Interceptor

On the admin panel side, window.fetch is patched to watch for a special header:

  ๐ŸŒ Admin makes any API call
       โ”‚
       โ–ผ
  ๐Ÿ‘€ Check response headers for 'app.admin.tk'
       โ”‚
       YES โ†’ ๐Ÿšจ FORCED LOGOUT ๐Ÿšจ
       โ”‚     window.stop()
       โ”‚     window.location.reload()
       โ”‚     (Session is over. Go home.)
       โ”‚
       NO  โ†’ โœ… Normal response. Continue working.

๐Ÿ“‚ Project Structure

strapi-security-suite/
๐Ÿ“ admin/src/                    โ† Admin panel (React)
โ”‚   ๐Ÿ“„ index.js                    Plugin entry + fetch interceptor
โ”‚   ๐Ÿ“„ constants.js                API paths, header names
โ”‚   ๐Ÿ“„ pluginId.js                 Plugin ID constant
โ”‚   ๐Ÿ“ components/
โ”‚   โ”‚   ๐Ÿ“„ Initializer.jsx         Plugin lifecycle init
โ”‚   ๐Ÿ“ pages/
โ”‚   โ”‚   ๐Ÿ“„ App.jsx                 Router
โ”‚   โ”‚   ๐Ÿ“„ HomePage.jsx            Settings UI (the pretty one)
โ”‚   ๐Ÿ“ translations/
โ”‚       ๐Ÿ“„ en.json                 i18n strings
โ”‚
๐Ÿ“ server/src/                   โ† Server-side (Node.js)
โ”‚   ๐Ÿ“„ index.js                    Plugin entry point
โ”‚   ๐Ÿ“„ register.js                 Middleware registration phase
โ”‚   ๐Ÿ“„ bootstrap.js                Permissions + settings seeding
โ”‚   ๐Ÿ“„ destroy.js                  Cleanup on shutdown
โ”‚   ๐Ÿ“„ constants.js                โญ ALL magic values live here
โ”‚   โ”‚
โ”‚   ๐Ÿ“ controllers/
โ”‚   โ”‚   ๐Ÿ“„ adminSecurityController.js   GET/POST settings (with validation!)
โ”‚   โ”‚
โ”‚   ๐Ÿ“ services/
โ”‚   โ”‚   ๐Ÿ“„ autoLogoutChecker.js    Background watcher (setInterval)
โ”‚   โ”‚
โ”‚   ๐Ÿ“ middlewares/
โ”‚   โ”‚   ๐Ÿ“„ seedUserInfos.js        Hydrate session from JWT
โ”‚   โ”‚   ๐Ÿ“„ interceptRenewToken.js  Block renewal for dead sessions
โ”‚   โ”‚   ๐Ÿ“„ trackActivity.js        Record last activity timestamp
โ”‚   โ”‚   ๐Ÿ“„ rejectRevokedTokens.js  Nuke revoked sessions
โ”‚   โ”‚   ๐Ÿ“„ preventMultipleSessions.js  One-session-per-admin gate
โ”‚   โ”‚
โ”‚   ๐Ÿ“ policies/
โ”‚   โ”‚   ๐Ÿ“„ has-admin-permission.js  Route-level permission check
โ”‚   โ”‚
โ”‚   ๐Ÿ“ globals/                  โ† In-memory state (the "brain")
โ”‚   โ”‚   ๐Ÿ“„ sessionActivityMap.js   Map<"id:email", timestamp>
โ”‚   โ”‚   ๐Ÿ“„ revokedTokenSet.js      Set<email> of revoked sessions
โ”‚   โ”‚   ๐Ÿ“„ loginLocks.js           Set<email> login race-condition guard
โ”‚   โ”‚
โ”‚   ๐Ÿ“ utils/
โ”‚   โ”‚   ๐Ÿ“„ errors.js               PluginError, ValidationError, AuthorizationError
โ”‚   โ”‚   ๐Ÿ“„ force-expire-admin.js   Issue a 1-second JWT to kill client token
โ”‚   โ”‚
โ”‚   ๐Ÿ“ content-types/
โ”‚   โ”‚   ๐Ÿ“ security-settings/
โ”‚   โ”‚       ๐Ÿ“„ schema.json          DB schema (singleType)
โ”‚   โ”‚
โ”‚   ๐Ÿ“ routes/
โ”‚   โ”‚   ๐Ÿ“„ index.js                Admin-typed routes with policies
โ”‚   โ”‚
โ”‚   ๐Ÿ“ types/
โ”‚       ๐Ÿ“„ typedefs.js             JSDoc type definitions
โ”‚
๐Ÿ“„ eslint.config.mjs               ESLint v9 flat config
๐Ÿ“„ .prettierrc                     Prettier config
๐Ÿ“„ package.json                    Scripts, deps, lint-staged
๐Ÿ“ .husky/
    ๐Ÿ“„ pre-commit                  Runs lint-staged before every commit

๐Ÿ”ง Configuration Schema

All settings live in a single-type content-type in the database:

{
  "autoLogoutTime": 30,
  "multipleSessionsControl": true,
  "passwordExpiryDays": 30,
  "nonReusablePassword": true,
  "enablePasswordManagement": true
}
Field Type Default What It Does
autoLogoutTime integer 30 Minutes of inactivity before auto-logout
multipleSessionsControl boolean true Block concurrent sessions for same admin
passwordExpiryDays integer 30 Days before password must be changed
nonReusablePassword boolean true Prevent reuse of previous passwords
enablePasswordManagement boolean true Master switch for password features

๐Ÿงช API Endpoints

All routes are admin-typed (Strapi handles auth automatically):

Method Path Auth Permission Description
GET /strapi-security-suite/health ๐Ÿ”“ None โ€” Health check
GET /strapi-security-suite/admin/settings ๐Ÿ”’ Admin view-configs Read settings
POST /strapi-security-suite/admin/settings ๐Ÿ”’ Admin manage-configs Update settings

๐Ÿ” Permissions

The plugin registers three permission actions:

Permission What It Allows
plugin::strapi-security-suite.access Access the settings page
plugin::strapi-security-suite.view-configs Read security settings
plugin::strapi-security-suite.manage-configs Modify security settings

โœ… Engineering Standards Compliance

This plugin follows the STANDARDS.md operating protocol:

Standard Status Details
๐Ÿ’ฌ ES6+ JavaScript โœ… Arrow functions, destructuring, template literals, native ESM
๐Ÿ“„ Full JSDoc โœ… Every export documented with @param, @returns, @module
๐Ÿ”ข No Magic Values โœ… All values in constants.js (status codes, cookies, headers, timing)
๐Ÿšจ Custom Error Hierarchy โœ… PluginError โ†’ ValidationError, AuthorizationError
๐Ÿ›ก๏ธ Input Validation โœ… saveSettings validates keys, types, and shape
๐Ÿ” ESLint โœ… v9 flat config with jsdoc plugin + Prettier compat
๐ŸŽจ Prettier โœ… Single quotes, 100 print width, trailing commas
๐Ÿช Husky + lint-staged โœ… Pre-commit: ESLint fix + Prettier on staged files
๐Ÿ—๏ธ Architecture โœ… Routes โ†’ Controllers โ†’ Services โ†’ Data (proper layering)
๐Ÿ” Security-First โœ… Auth/AuthZ separated, input validated, no secrets in logs

๐Ÿ› ๏ธ Development

# Install dependencies
yarn install

# Build the plugin
yarn build

# Watch mode (auto-rebuild on changes)
yarn watch

# Lint everything
yarn lint

# Lint + auto-fix
yarn lint:fix

# Check formatting
yarn format:check

# Auto-format everything
yarn format

# Verify plugin exports
yarn verify

๐Ÿ”ฎ Roadmap

Feature Status
โฐ Auto-Logout โœ… Shipped
๐Ÿšซ Single-Session Enforcement โœ… Shipped
๐Ÿ’€ Token Revocation Pipeline โœ… Shipped
โš™๏ธ Admin Settings UI โœ… Shipped
๐Ÿ”‘ Password Expiry ๐Ÿšง In Development
๐Ÿ”„ Non-Reusable Passwords ๐Ÿšง In Development
๐Ÿ“ Admin Activity Logs ๐Ÿ”œ Planned
๐Ÿ“Š Security Dashboard ๐Ÿ”œ Planned
๐Ÿ‘Š Brute Force Detection ๐Ÿ”œ Planned
๐Ÿ‘๏ธ Real-time Session Viewer ๐Ÿ”œ Planned

๐Ÿ—ฃ๏ธ Real Talk

"We installed this and now our interns can't share logins anymore." โ€” A CTO, probably

"Our admin panel feels like it judges us now. I love it." โ€” That one developer who actually cares

"I left my desk for coffee and came back logged out. Respect." โ€” Someone who now understands security


๐Ÿ‘ฅ Author

LPIX-11 โ€” Orange / Sonatel


โš–๏ธ License

MIT โ€” Do whatever you want. Just don't blame us if you turn off all the features and get breached. That's on you.


๐Ÿ’ก Philosophy

Security should be:

  • Fast โ€” In-memory. No database lookups on every request.
  • Unforgiving โ€” Idle? Gone. Revoked? Dead. Duplicated? Blocked.
  • Elegant โ€” Clean constants, typed errors, layered architecture.
  • Mildly judgmental โ€” This plugin will side-eye your stale sessions.

"The meta-principle: make the right thing the default thing. Discipline compounds. Shortcuts compound too, just in the wrong direction."

About

A high-performance, in-memory security enhancement plugin for Strapi v5, Session-obsessed.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors