{"id":13632316,"url":"https://github.com/instantcommerce/next-password-protect","last_synced_at":"2025-04-13T00:48:44.725Z","repository":{"id":37823202,"uuid":"343918773","full_name":"instantcommerce/next-password-protect","owner":"instantcommerce","description":"Password protect your Next.js projects.","archived":false,"fork":false,"pushed_at":"2023-02-04T16:32:58.000Z","size":4344,"stargazers_count":320,"open_issues_count":20,"forks_count":19,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-13T00:48:36.560Z","etag":null,"topics":["authentication","deployment","hoc","nextjs","react","typescript"],"latest_commit_sha":null,"homepage":"https://next-password-protect.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/instantcommerce.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-03-02T21:33:35.000Z","updated_at":"2025-04-07T13:46:33.000Z","dependencies_parsed_at":"2023-02-08T09:15:50.866Z","dependency_job_id":null,"html_url":"https://github.com/instantcommerce/next-password-protect","commit_stats":null,"previous_names":["storyofams/next-password-protect"],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instantcommerce%2Fnext-password-protect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instantcommerce%2Fnext-password-protect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instantcommerce%2Fnext-password-protect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instantcommerce%2Fnext-password-protect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/instantcommerce","download_url":"https://codeload.github.com/instantcommerce/next-password-protect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650436,"owners_count":21139672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","deployment","hoc","nextjs","react","typescript"],"created_at":"2024-08-01T22:02:59.660Z","updated_at":"2025-04-13T00:48:44.705Z","avatar_url":"https://github.com/instantcommerce.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca aria-label=\"Instant Commerce logo\" href=\"https://instantcommerce.io/\" target=\"_blank\" align=\"center\"\u003e\n    \u003cimg src=\"https://avatars.githubusercontent.com/u/93975473\" alt=\"Instant Commerce\" width=\"100\"\u003e\n  \u003c/a\u003e\n  \u003ch1 align=\"center\"\u003enext-password-protect\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca aria-label=\"releases\" href=\"https://github.com/instantcommerce/next-password-protect/releases/\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://github.com/instantcommerce/next-password-protect/workflows/Release/badge.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca aria-label=\"npm\" href=\"https://www.npmjs.com/package/next-password-protect\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/npm/v/next-password-protect\"\u003e\n    \u003c/a\u003e\n    \u003ca aria-label=\"codecov\" href=\"https://codecov.io/gh/instantcommerce/next-password-protect\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://codecov.io/gh/instantcommerce/next-password-protect/branch/master/graph/badge.svg?token=ZV0YT4HU5H\"\u003e\n    \u003c/a\u003e\n    \u003ca aria-label=\"stars\" href=\"https://github.com/instantcommerce/next-password-protect/stargazers/\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/stars/instantcommerce/next-password-protect.svg?style=social\u0026label=Star\u0026maxAge=86400\" /\u003e\n    \u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003ePassword protect your Next.js deployments. \u003ca href=\"http://next-password-protect.vercel.app/\" target=\"_blank\"\u003eView demo\u003c/a\u003e (Password is \u003cb\u003esecret\u003c/b\u003e)\u003c/p\u003e\n\u003c/p\u003e\n\n---\n\n[![Preview](https://user-images.githubusercontent.com/19343479/110955791-3da56480-834a-11eb-9e7c-6b17621ba346.png)](https://user-images.githubusercontent.com/19343479/114987129-1a179180-9e95-11eb-9508-6c514f671ca9.mov)\n\n## How it works\n\nThis library adds a password prompt to your Next.js deployment. It consists of two main parts:\n1. Two serverless API routes:\n   - A login route that checks if a password is correct and sets a cookie with a JWT in case it is.\n   - A check route that validates if you have the authorization cookie with a valid JWT.\n2. A HOC ([Higher-Order Component](https://reactjs.org/docs/higher-order-components.html)) that wraps Next.js App and adds a check that validates if you are logged in. If you do, then you can view the app normally; otherwise, you are presented with a password prompt.\n\n**Important**: The recommended use case for this library is in a staging or preview environment. By taking advantage of webpack's `DefinePlugin`, we can make sure this library is only included in certain environments, keeping the production bundle size small.\n\n**This library is NOT meant as a secure password authentication wrapper, but rather as a way to keep nosey people out.**\n\n## Installation\n\n```sh\nyarn add next-password-protect\n# or\nnpm install next-password-protect\n```\n\n## Usage\n\nThere are 3 steps to enabling password protect: setting a global variable, adding the API routes, and adding the HOC to \\_app.\n\n### Step 1\n\nIn order to be able to take advantage of dead code elimination, it is recommended to add an environment variable like `process.env.PASSWORD_PROTECT`, and enable the library based on that variable. To set this variable, add the following to `next.config.js`:\n\n```javascript\nmodule.exports = {\n  env: {\n    // Add any logic you want here, returning `true` to enable password protect.\n    PASSWORD_PROTECT: process.env.ENVIRONMENT === 'staging',\n  }\n});\n```\n\n### Step 2\n\nAdd two api routes, one with the `loginHandler` and one with the `passwordCheckHandler` api function. You can name them anything, as long as you pass the names to `loginApiUrl` and `checkApiUrl` respectively, in the next step. By default it expects `/login` and `/passwordCheck`.\n\n```javascript\nimport { loginHandler } from \"next-password-protect\";\n\nexport default loginHandler(\"YOUR_SECRET_PASSWORD\", {\n  // Options go here (optional)\n  cookieName: \"next-password-protect\",\n});\n```\n\n```javascript\nimport { passwordCheckHandler } from \"next-password-protect\";\n\nexport default passwordCheckHandler(\"YOUR_SECRET_PASSWORD\", {\n  // Options go here (optional)\n  cookieName: \"next-password-protect\",\n});\n```\n\n### Step 3\n\nAdd the `withPasswordProtect` HOC to the default export of `App` in `pages/_app.tsx`:\n\n```javascript\nimport { withPasswordProtect } from \"next-password-protect\";\n\n// Before: export default App;\nexport default process.env.PASSWORD_PROTECT\n  ? withPasswordProtect(App, {\n    // Options go here (optional)\n    loginApiUrl: \"/login\",\n  })\n  : App;\n```\n\n**Note**: make sure to specify `loginApiUrl` and/or `checkApiUrl` if the api route(s) are not default.\n\n## API\n\n### API routes handlers\n```loginHandler(password: string, options)```\n\nThe options object can contain any of the following options:\n\nOption | Description | Default value\n------ | ----------- | -------------\n`cookieMaxAge`| Cookie Max-Age attribute | `undefined`\n`cookieName`| The name of the authorization cookie | `'next-password-protect'`\n`cookieSameSite`| SameSite cookie attribute | `false`\n`cookieSecure`| Secure flag on the cookie | `process.env.NODE_ENV === 'production'`\n\n```passwordCheckHandler(password: string, options)```\n\nThe options object can contain any of the following options:\n\nOption | Description | Default value\n------ | ----------- | -------------\n`cookieName`| The name of the authorization cookie | `'next-password-protect'`\n\n\n### Next App HOC\n```withPasswordProtect(App: NextApp, options)```\n\nThe options object can contain any of the following options:\n\nOption | Description | Default value\n------ | ----------- | -------------\n`checkApiUrl`| Relative path of the api route handled by `passwordCheckHandler` | `'/api/passwordCheck'`\n`loginApiUrl`| Relative path of the api route handled by `loginHandler` | `'/api/login'`\n`loginComponent`| Supply your own React component to show as login prompt | `LoginComponent`\n`loginComponentProps`| Properties object to customize the login prompt, without overriding the entire component (see below) | `{}`\n`bypassProtection`| Bypass protection for specific routes, decided by callback with `NextRouter` param | `({ route }) =\u003e false`\n\nThe `loginComponentProps` object can contain any of the following options:\n\nOption | Description | Default value\n------ | ----------- | -------------\n`backUrl`| Show a link with this URL to go back to main website | `undefined`\n`buttonBackgroundColor`| Login button background color | `'#01EDBC'`\n`buttonColor`| Login button color | `'#111'`\n`logo` | Show a logo above the prompt (img src) | `undefined`\n\n## Advanced\n\n### Custom login component\n\nTo change the default login component, a React component can be supplied to the `withPasswordProtect` HOC. In order for the library to function properly, make sure your login component has password input that is validated by the the api route.\nYou can use `src/hoc/LoginComponent.tsx` as a starting point.\n\n## Caveats\n\nAMP is not yet supported, because the LoginComponent failed AMP validation. On an AMP page, nothing is rendered. This could be fixed by changing LoginComponent to valid AMP.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstantcommerce%2Fnext-password-protect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finstantcommerce%2Fnext-password-protect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstantcommerce%2Fnext-password-protect/lists"}