├── .npmrc ├── .prettierignore ├── .gitignore ├── src ├── __test__ │ └── index.spec.ts └── index.ts ├── .npmignore ├── .editorconfig ├── CHANGELOG.md ├── puggle.json ├── tsconfig.json ├── LICENSE ├── package.json └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # 2 | # Files for prettier to ignore 3 | # 4 | 5 | coverage 6 | node_modules 7 | dist 8 | .nova 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Files to ignore from git source control 3 | # 4 | 5 | *.env 6 | .DS_Store 7 | node_modules 8 | coverage 9 | dist 10 | package-lock.json 11 | -------------------------------------------------------------------------------- /src/__test__/index.spec.ts: -------------------------------------------------------------------------------- 1 | // 2 | // An example unit test 3 | // 4 | 5 | describe('sample', () => { 6 | it('should pass', () => { 7 | expect(1 + 1).toBe(2) 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # 2 | # Files to ignore from npm 3 | # https://npm.github.io/publishing-pkgs-docs/publishing/the-npmignore-file.html 4 | # 5 | 6 | *.env 7 | coverage 8 | 9 | __tests__ 10 | __mocks__ 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Editor config, for sharing IDE preferences ~ https://editorconfig.org/ 3 | # 4 | 5 | root = true 6 | 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | end_of_line = lf 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.1.1 2 | 3 | - Explicitly set the `Content-Type` to be `text/html` to prevent 4 | errors when `X-Content-Type-Options: nosniff` is set. 5 | 6 | Thanks to [Michał Miszczyszyn](https://github.com/mmiszy). 7 | 8 | ## 1.1.0 9 | 10 | - expose `oauthConfig`, `randomState` and `renderResponse` methods 11 | to allow repurposing of the internals for non-vercel contexts. 12 | - add `OAUTH_HOST`, `OAUTH_TOKEN_PATH` and `OAUTH_AUTHORIZE_PATH` 13 | environment variables for more configuration. 14 | 15 | ## 1.0.0 16 | 17 | Initial release 18 | -------------------------------------------------------------------------------- /puggle.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.5.5", 3 | "projectName": "vercel-netlify-cms-github", 4 | "preset": { 5 | "name": "robb-j:ts-node", 6 | "version": "0.2.2" 7 | }, 8 | "plugins": { 9 | "npm": "0.1.0" 10 | }, 11 | "params": { 12 | "npm": { 13 | "packageName": "@openlab/vercel-netlify-cms-github", 14 | "packageInfo": "Vercel API routes to login to netlify-cms deployed on vercel", 15 | "repository": "digitalinteraction/vercel-netlify-cms-github" 16 | }, 17 | "cli": { 18 | "enabled": false 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "target": "es2019", // Node.js 12 5 | "module": "commonjs", 6 | "sourceMap": true, 7 | "declaration": true, 8 | "newLine": "lf", 9 | "stripInternal": true, 10 | "strict": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noEmitOnError": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "skipLibCheck": true, 16 | "resolveJsonModule": true, 17 | "typeRoots": ["./node_modules/@types", "./src/types"] 18 | }, 19 | "include": ["src"], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Newcastle University 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@openlab/vercel-netlify-cms-github", 3 | "description": "Vercel API routes to login to netlify-cms deployed on vercel", 4 | "version": "1.1.1", 5 | "repository": "digitalinteraction/vercel-netlify-cms-github", 6 | "author": "", 7 | "license": "MIT", 8 | "scripts": { 9 | "test": "jest", 10 | "coverage": "jest --coverage", 11 | "build": "tsc", 12 | "lint": "tsc --noEmit", 13 | "prettier": "prettier --write '**/*.{js,json,css,md,ts,tsx}'", 14 | "preversion": "npm run test -s && npm run build" 15 | }, 16 | "keywords": [], 17 | "engines": { 18 | "node": ">=12" 19 | }, 20 | "dependencies": { 21 | "dedent": "^0.7.0", 22 | "dotenv": "^8.2.0", 23 | "simple-oauth2": "^4.2.0" 24 | }, 25 | "devDependencies": { 26 | "@types/dedent": "^0.7.0", 27 | "@types/jest": "^26.0.20", 28 | "@types/node": "^14.14.22", 29 | "@types/simple-oauth2": "^4.1.0", 30 | "@vercel/node": "^1.9.0", 31 | "jest": "^26.6.3", 32 | "lint-staged": "^10.5.3", 33 | "nodemon": "^2.0.7", 34 | "prettier": "^2.2.1", 35 | "ts-jest": "^26.4.4", 36 | "ts-node": "^8.10.2", 37 | "typescript": "^3.9.7", 38 | "yorkie": "^2.0.0" 39 | }, 40 | "jest": { 41 | "preset": "ts-jest", 42 | "testEnvironment": "node", 43 | "testPathIgnorePatterns": [ 44 | "/node_modules/", 45 | "/dist/" 46 | ] 47 | }, 48 | "prettier": { 49 | "semi": false, 50 | "singleQuote": true 51 | }, 52 | "gitHooks": { 53 | "pre-commit": "lint-staged" 54 | }, 55 | "lint-staged": { 56 | "*.{js,json,css,md,ts,tsx}": [ 57 | "prettier --write" 58 | ] 59 | }, 60 | "main": "dist/index.js", 61 | "types": "dist/index.d.js" 62 | } 63 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // From https://github.com/robinpokorny/netlify-cms-now 3 | // with the goal of moving to a reusable npm module 4 | // 5 | 6 | import dedent = require('dedent') 7 | import { NowRequest, NowResponse } from '@vercel/node' 8 | import { randomBytes } from 'crypto' 9 | import { AuthorizationCode, ModuleOptions } from 'simple-oauth2' 10 | 11 | const { 12 | OAUTH_CLIENT_ID = '', 13 | OAUTH_CLIENT_SECRET = '', 14 | OAUTH_HOST = 'https://github.com', 15 | OAUTH_TOKEN_PATH = '/login/oauth/access_token', 16 | OAUTH_AUTHORIZE_PATH = '/login/oauth/authorize', 17 | } = process.env 18 | 19 | export const oauthConfig: ModuleOptions = Object.freeze({ 20 | client: Object.freeze({ 21 | id: OAUTH_CLIENT_ID!, 22 | secret: OAUTH_CLIENT_SECRET, 23 | }), 24 | auth: Object.freeze({ 25 | tokenHost: OAUTH_HOST, 26 | tokenPath: OAUTH_TOKEN_PATH, 27 | authorizePath: OAUTH_AUTHORIZE_PATH, 28 | }), 29 | }) 30 | 31 | export function randomState() { 32 | return randomBytes(6).toString('hex') 33 | } 34 | 35 | /** Render a html response with a script to finish a client-side github authentication */ 36 | export function renderResponse(status: 'success' | 'error', content: any) { 37 | return dedent` 38 | 39 | 40 |
41 | 42 |