Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ add nuxt support #9

Merged
merged 9 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions examples/next/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import session from "express-session";
import { createServer, IncomingMessage, ServerResponse } from "http";
import next from "next";
import { staging } from "staging";
import staging from "staging";
import { parse } from "url";

const port = parseInt(process.env.PORT || "3000", 10);
Expand Down Expand Up @@ -39,13 +39,7 @@
// Apply password protection middleware
expressApp.use(
staging({
password: process.env.SITE_PASSWORD || "1234",
// Explicitly set public routes if needed
publicRoutes: ["/_next/static/.*", "/api/public/.*"],
// Optional: specify protected routes (by default, all routes are protected)
// protectedRoutes: ['/admin', '/dashboard'],
redirectUrl: "/", // Default redirect after login
siteName: process.env.SITE_NAME || "Protected Site",
}),
);

Expand All @@ -63,7 +57,7 @@
const handler = expressApp as unknown as (
req: IncomingMessage,
res: ServerResponse,
next: (err?: any) => void,

Check warning on line 60 in examples/next/server.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test on Node 20.x and ubuntu-latest

Unexpected any. Specify a different type
) => void;

// Run the Express middleware stack
Expand Down
24 changes: 24 additions & 0 deletions examples/nuxt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist

# Node dependencies
node_modules

# Logs
logs
*.log

# Misc
.DS_Store
.fleet
.idea

# Local env files
.env
.env.*
!.env.example
75 changes: 75 additions & 0 deletions examples/nuxt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Nuxt Minimal Starter

Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.

## Setup

Make sure to install dependencies:

```bash
# npm
npm install

# pnpm
pnpm install

# yarn
yarn install

# bun
bun install
```

## Development Server

Start the development server on `http://localhost:3000`:

```bash
# npm
npm run dev

# pnpm
pnpm dev

# yarn
yarn dev

# bun
bun run dev
```

## Production

Build the application for production:

```bash
# npm
npm run build

# pnpm
pnpm build

# yarn
yarn build

# bun
bun run build
```

Locally preview production build:

```bash
# npm
npm run preview

# pnpm
pnpm preview

# yarn
yarn preview

# bun
bun run preview
```

Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
7 changes: 7 additions & 0 deletions examples/nuxt/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<div>
<NuxtRouteAnnouncer />
<NuxtWelcome />
</div>
</template>
;
20 changes: 20 additions & 0 deletions examples/nuxt/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// nuxt.config.ts
export default defineNuxtConfig({
// Runtime config
runtimeConfig: {
stagingPassword: process.env.STAGING_PASSWORD,
sessionSecret: process.env.SESSION_SECRET,
},

// Dev server config
devServer: {
port: 3000,
},

// Nitro config
nitro: {
// You can add specific nitro config here if needed
},

compatibilityDate: "2024-11-18",
});
18 changes: 18 additions & 0 deletions examples/nuxt/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "nuxt",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@staging/nuxt": "workspace:*",
"nuxt": "^3.14.159",
"vue": "latest",
"vue-router": "latest"
}
}
Binary file added examples/nuxt/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions examples/nuxt/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

5 changes: 5 additions & 0 deletions examples/nuxt/server/middleware/staging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { stagingMiddleware } from "@staging/nuxt";

export default stagingMiddleware({
password: "demo",
});
3 changes: 3 additions & 0 deletions examples/nuxt/server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}
4 changes: 4 additions & 0 deletions examples/nuxt/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}
77 changes: 77 additions & 0 deletions packages/nuxt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# @staging/nuxt

Nuxt.js integration for [staging](https://github.com/AntoineKM/staging) password protection middleware.

[![npm version](https://img.shields.io/npm/v/@staging/nuxt.svg)](https://www.npmjs.com/package/@staging/nuxt)
[![Bundle Size](https://img.shields.io/bundlephobia/minzip/@staging/nuxt)](https://bundlephobia.com/package/@staging/nuxt)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)

## Overview

For full documentation and features, please refer to the [main staging documentation](../../README.md).

This package provides Nuxt.js integration for the staging password protection middleware.

## Installation

```bash
npm install @staging/nuxt
# or
yarn add @staging/nuxt
# or
pnpm add @staging/nuxt
```

## Usage

Create a server middleware file in your Nuxt.js project:

```typescript
// server/middleware/staging.ts
import { stagingMiddleware } from "@staging/nuxt";

export default stagingMiddleware({
password: process.env.STAGING_PASSWORD || "your-password",
});
```

## Nuxt.js Specific Defaults

The middleware comes with Nuxt.js-specific public routes:

```typescript
const defaultOptions = {
siteName: "Protected Nuxt Page",
publicRoutes: [
"/_nuxt/*",
"/api/_content/*",
"/__nuxt_error",
"/favicon.ico",
"/assets/*",
"/_ipx/*",
]
};
```

You can add additional public or protected routes while keeping these defaults:

```typescript
export default stagingMiddleware({
password: process.env.STAGING_PASSWORD,
publicRoutes: [
"^/public(/.*)?$",
"^/api/public(/.*)?$"
] // These will be merged with default public routes
});
```

## License

[MIT](../../LICENSE)

***

<p align="center">
<sub>Built with ❤️ by <a href="https://github.com/AntoineKM">Antoine Kingue</a></sub>
</p>
40 changes: 40 additions & 0 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@staging/nuxt",
"version": "0.0.0",
"description": "Nuxt module for staging password protection",
"repository": {
"type": "git",
"url": "git+https://github.com/AntoineKM/staging.git"
},
"bugs": {
"url": "https://github.com/AntoineKM/staging/issues"
},
"homepage": "https://github.com/AntoineKM/staging/tree/master/packages/nuxt",
"license": "MIT",
"author": "Antoine Kingue <[email protected]>",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsup",
"dev": "tsup --watch"
},
"dependencies": {
"cookie-parser": "^1.4.7",
"express": "^4.21.1",
"express-session": "^1.18.1",
"h3": "^1.13.0",
"staging": "workspace:*"
},
"devDependencies": {
"@types/cookie-parser": "^1.4.7",
"@types/express": "^4.17.21",
"@types/express-session": "^1.18.0",
"@types/node": "^22.0.0",
"tsup": "^8.0.1",
"typescript": "^5.3.2"
}
}
68 changes: 68 additions & 0 deletions packages/nuxt/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import cookieParser from "cookie-parser";
import crypto from "crypto";
import express, { Request, Response } from "express";
import session from "express-session";
import { defineEventHandler, createError } from "h3";
import staging, { StagingOptions } from "staging";

const defaultOptions = {
siteName: "Protected Nuxt Page",
publicRoutes: [
"/_nuxt/*",
"/api/_content/*",
"/__nuxt_error",
"/favicon.ico",
"/assets/*",
"/_ipx/*",
] as string[],
} as const;

export const stagingMiddleware = (options: StagingOptions) => {
const stagingApp = express();
stagingApp.use(express.urlencoded({ extended: true }));
stagingApp.use(cookieParser());
stagingApp.use(
session({
secret: crypto.randomBytes(32).toString("hex"),
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === "production",
httpOnly: true,
sameSite: "lax",
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
},
}),
);

const middleware = staging({
...defaultOptions,
...options,
publicRoutes: [
...defaultOptions.publicRoutes,
...(options.publicRoutes || []),
],
});

stagingApp.use(middleware);

return defineEventHandler(async (event) => {
const req = event.node.req as Request;
const res = event.node.res as Response;

return new Promise<void>((resolve, reject) => {
stagingApp(req, res, (err: unknown) => {
if (err) {
reject(
createError({
statusCode: 500,
message: "Authentication middleware error",
}),
);
} else {
resolve();
}
});
});
});
};
19 changes: 19 additions & 0 deletions packages/nuxt/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020"],
"moduleResolution": "node",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"declaration": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"types": ["node"],
},
"include": ["./**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Loading
Loading