Lexiverse
Lexiverse - AI contextual reading engine for English learners. Your next article is your next review.
Open-access scientific publishing. Browse peer-reviewed journals, current issues, and archived research articles on DigitoPub.
Translation pending
EducationTypeScript · SmartyGitHub @mohammed3200OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A comprehensive digital publishing platform for academic and scientific journals by DigitoPub, built with Next.js, Prisma, and MySQL.
Clone the repository
git clone <repository-url>
cd scientific-journals-website
Install dependencies
npm install
# or
bun install
Set up environment variables
cp .env.example .env
Edit .env and configure your database credentials:
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_NAME=scientific_journals
DATABASE_USER=app_user
DATABASE_PASSWORD=your_password
# Optional: OJS Integration
OJS_DATABASE_HOST=localhost
OJS_DATABASE_NAME=ojs_db
OJS_DATABASE_USER=ojs_readonly
OJS_DATABASE_PASSWORD=readonly_password
Start MySQL with Docker (Optional)
docker-compose up -d
This will start MySQL 8.0 with automatic schema initialization.
Run database migrations (if not using Docker)
mysql -u app_user -p scientific_journals < scripts/001_create_tables.sql
mysql -u app_user -p scientific_journals < scripts/002_insert_sample_data.sql
Generate Prisma Client
npx prisma generate
# or
bunx prisma generate
Start the development server
npm run dev
Visit http://localhost:3000 to see your application.
This project uses MySQL (migrated from PostgreSQL) with the following key features:
# Verify MySQL connection
npm run db:verify
# or
bun run db:verify
# Run migrations manually
npm run db:migrate
# or
bun run db:migrate
# Seed with sample data
npm run db:seed
# or
bun run db:seed
The system operates across two strict boundaries:
The primary content flow is author → DigitoPub → SubmitManager/OJS → canonical OJS data → DigitoPub sync → public reader. The read mirror is refreshed by scheduled full syncs and drift detection. Approved admin writes, such as specialization changes, use a separate audited user-bridge path with queued retries; specialization remains digitopub-owned and is not read back.
Download the interactive architecture diagram (self-contained HTML with light/dark themes and export) · PNG preview
digitopub now holds TWO independent identity systems:
auth_token cookie, JWT via jose): unchanged. Used for /admin/* routes only. Helpers live in src/lib/db/auth.ts.digitopub_identity cookie, HMAC-signed): added by UIET-P1. Used to gate non-OA PDF actions and attribute engagement events. ORCID is the SOLE identity provider — digitopub never sees passwords, never validates credentials, never stores email/password tuples. Helpers live in src/lib/identity-cookie.ts.The two cookies are wholly separate code paths and MUST NOT cross-pollinate.
/account/stats (their own engagement breakdown) and /account/data (right-to-erasure). The OAuth flow round-trips through orcid.org and returns the user to the page they came from.digitopub_identity is HMAC-signed (IDENTITY_COOKIE_SECRET), 30 min sliding expiry, 8 h absolute expiry, ±2 min skew tolerance. Host-only on digitopub.com, httpOnly; Secure; SameSite=Lax./api/pdf-proxy serves any galley to any visitor. The proxy may inspect the cookie for attribution but never blocks. An earlier draft of UIET-P1 gated non-OA PDFs; that gate was dropped before launch on open-access principle.ENABLE_ORCID_OJS_BACKFILL=true, we write the ORCID iD back into OJS user_settings. Every such write is audited in audit_ojs_writes. Default OFF in production.user_event rows are written for every view, download, and citation export. The digitopub_consent cookie controls what is recorded:
all — orcid (when signed in), daily-rotating IP hash, daily-rotating UA hash.essential_only — orcid only; no IP/UA.pre_consent (no choice yet) — fully anonymous: source='pre_consent', no orcid, no IP/UA.Aggregation crons live in scripts/aggregate-daily-metrics.ts, aggregate-monthly-metrics.ts, update-user-metrics.ts, and retention-cleanup.ts.
Single Sign-On (SSO) for the registration path is still a one-way token-based bootstrap used exclusively after a new user registers on digitopub. The registration API provisions the user in OJS and redirects them with a 5-minute expiry HMAC token to log them securely into OJS the very first time. SSO is not used for returning users.
getSession() or jose.jwtVerify in any public route (under app/ excluding app/admin/**, or under src/server/routes/). The ESLint rule no-restricted-imports enforces this; CI greps as a backup.getIdentity(request) from src/lib/identity-cookie.ts for public-user identity. It is sibling to admin auth, never invokes it.src/lib/ojs-write-guard.ts (writeOrcidToOjsWithAudit() and setJournalSpecializationInOjsWithAudit()). Every write produces an audit row.UIET_P1_ENABLED until the rollout finishes.getSession() in a public route: that is the admin pathway. Use getIdentity().src/lib/ojs-write-guard.ts so it lands in audit_ojs_writes.The system enforces a strict Dual Authentication Model where public users are isolated from the admin gateway.
When a new user registers on digitopub, a secure backend-to-backend provisioning process occurs:
ojs-user-bridge.php on the OJS server via a Bearer-authenticated POST request.base64(payload).signature) valid for 5 minutes.sso_login.php?token=... on the OJS domain.sso_login.php validates the token via digitopub's GET /api/ojs/sso/validate and initializes a native OJS session.sequenceDiagram
participant U as User (Browser)
participant DP as Digitopub (Next.js)
participant Bridge as ojs-user-bridge.php (OJS)
participant DB as OJS MySQL
participant SSO as sso_login.php (OJS)
U->>DP: Submit Registration Wizard
DP->>Bridge: POST /ojs-user-bridge.php (API Key)
Bridge->>DB: INSERT INTO users/user_settings
Bridge-->>DP: HTTP 201 Created
DP->>DP: Sign Stateless HMAC Token
DP-->>U: Redirect to sso_login.php?token=...
U->>SSO: GET /sso_login.php?token=...
SSO->>DP: GET /api/ojs/sso/validate?token=...
DP-->>SSO: { valid: true, email: "..." }
SSO->>SSO: Bootstrap native OJS Session
SSO-->>U: 302 Redirect to Submission Wizard
digitopub acts as a purely stateless gateway for returning users.
<Link> to the OJS submission wizard.POST /api/ojs/sso) that generates tokens based on client-provided emails.Create read-only MySQL user
CREATE USER 'ojs_readonly'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT ON ojs_db.* TO 'ojs_readonly'@'localhost';
FLUSH PRIVILEGES;
Test OJS connection
npm run ojs:verify
# or
bun run ojs:verify
Run initial sync
npm run ojs:sync
# or
bun run ojs:sync
Set up automated sync (optional)
# Add to crontab (runs every 6 hours)
0 */6 * * * cd /path/to/app && bun run scripts/ojs-sync-cron.ts >> /var/log/ojs-sync.log 2>&1
# Development
npm run dev # Start dev server (or bun run dev)
npm run build # Build for production (or bun run build)
npm run start # Start production server (or bun run start)
# Database
npm run db:migrate # Run MySQL migrations (or bun run db:migrate)
npm run db:seed # Seed database (or bun run db:seed)
npm run db:verify # Test database connection (or bun run db:verify)
# OJS Integration
npm run ojs:verify # Test OJS connection (or bun run ojs:verify)
npm run ojs:sync # Sync data from OJS (or bun run ojs:sync)
# Prisma
npx prisma generate # Generate Prisma client (or bunx prisma generate)
npx prisma studio # Open Prisma Studio GUI (or bunx prisma studio)
scientific-journals-website/
├── app/ # Next.js app directory
│ ├── admin/ # Admin dashboard pages
│ └── api/ # API routes
├── components/ # React components
├── lib/ # Utility libraries
│ ├── ojs-client.ts # OJS database client
│ ├── ojs-models.ts # OJS TypeScript types
│ └── ojs-service.ts # OJS business logic
├── prisma/
│ └── schema.prisma # Prisma schema (MySQL)
├── scripts/
│ ├── 001_create_tables.sql # Database schema
│ ├── 002_insert_sample_data.sql # Sample data
│ ├── ojs-sync-cron.ts # OJS sync script
│ ├── verify-mysql-connection.ts # MySQL test
│ └── verify-ojs-connection.ts # OJS test
└── docker-compose.yml # MySQL Docker setup
This project was migrated from PostgreSQL to MySQL. Key changes:
| Feature | PostgreSQL | MySQL |
|---|---|---|
| Primary Keys | UUID | BIGINT AUTO_INCREMENT |
| Arrays | TEXT[] | JSON |
| JSON | JSONB | JSON |
| Timestamps | TIMESTAMPTZ | DATETIME |
| Auth | Row Level Security | Application-level |
# Test MySQL connection
npm run db:verify
# Check MySQL is running
docker-compose ps
# or
systemctl status mysql
# Test OJS connection
npm run ojs:verify
# Check OJS credentials in .env
echo $OJS_DATABASE_HOST
# Regenerate Prisma client
bunx prisma generate
# Reset database (⚠️ deletes all data)
bunx prisma migrate reset
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)This project is private and proprietary.
Built with ❤️ by DigitoPub using Next.js, Prisma, and MySQL