Skip to content

Commit

Permalink
Merge pull request #255 from eduardoboucas/dev
Browse files Browse the repository at this point in the history
Add v3 endpoints (and GitLab support)
  • Loading branch information
eduardoboucas authored Mar 21, 2019
2 parents 3063604 + 4e2f33b commit 2be29f7
Show file tree
Hide file tree
Showing 42 changed files with 11,877 additions and 2,364 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
.idea/
*.iml

config.json
config.*.json
!config.test.json
!config.example.json
coverage/
node_modules/
staticman_key
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ cache:
notifications:
email: false
node_js:
- '6'
- '8.11.3'
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:6.7.0
FROM node:8.11.3

# Create app directory
RUN mkdir -p /app
Expand Down
31 changes: 2 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<img src="logo.png" width="300">

# Staticman [![coverage](https://img.shields.io/badge/coverage-53%25-red.svg?style=flat)](https://github.com/eduardoboucas/staticman) [![Build Status](https://travis-ci.org/eduardoboucas/staticman.svg?branch=master)](https://travis-ci.org/eduardoboucas/staticman) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
# Staticman [![coverage](https://img.shields.io/badge/coverage-81%25-yellow.svg?style=flat)](https://github.com/eduardoboucas/staticman) [![Build Status](https://travis-ci.org/eduardoboucas/staticman.svg?branch=master)](https://travis-ci.org/eduardoboucas/staticman) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)

> Static sites with superpowers
Expand All @@ -14,7 +14,7 @@ You can download and run the Staticman API on your own infrastructure, or you ca

## Requirements

- Node.js 4.8.3+
- Node.js 8.11.3+
- npm
- A [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) for the GitHub account you want to run Staticman with
- An SSH key (click [here](https://help.github.com/articles/connecting-to-github-with-ssh/) to learn how to create one)
Expand Down Expand Up @@ -78,30 +78,3 @@ Would you like to contribute to Staticman? That's great! Here's how:

- [Improving Static Comments with Jekyll & Staticman](https://mademistakes.com/articles/improving-jekyll-static-comments/)
- [Hugo + Staticman: Nested Replies and E-mail Notifications](https://networkhobo.com/2017/12/30/hugo---staticman-nested-replies-and-e-mail-notifications/)

## Sites using Staticman

- [Popcorn](http://popcorn.staticman.net) ([Source](https://github.com/eduardoboucas/popcorn))
- [eduardoboucas.com](https://eduardoboucas.com) ([Source](https://github.com/eduardoboucas/eduardoboucas.github.io))
- [Made Mistakes](https://mademistakes.com/) ([Source](https://github.com/mmistakes/made-mistakes-jekyll))
- [Minimal Mistakes theme](https://mmistakes.github.io/minimal-mistakes/) ([Source](https://github.com/mmistakes/minimal-mistakes))
- [/wg/ Startpages](http://startpages.cf/) ([Source](https://github.com/twentytwoo/startpages.cf))
- [mainstrea.ml](https://mainstrea.ml) ([Source](https://github.com/twentytwoo/mainstrea.ml))
- [Open Source Design Job Board](http://opensourcedesign.net/jobs/) ([Source](https://github.com/opensourcedesign/jobs/))
- [zongren.me](https://zongren.me/) ([Source](https://gitlab.com/zongren/zongren.gitlab.io/))
- [DOTSLASHLINUX](http://www.dotslashlinux.com/) ([Source](https://github.com/firasuke/DOTSLASHLINUX/))
- [Spinningnumbers.org](http://spinningnumbers.org/) ([Source](https://github.com/willymcallister/spinningnumbers))
- [blog.justin.kelly.org.au](https://blog.justin.kelly.org.au/) ([Source](github.com/justinkelly/justinkelly.github.io))
- [chimad-phase-field](https://pages.nist.gov/chimad-phase-field/) ([Source](https://github.com/usnistgov/chimad-phase-field))
- [abhinavsarkar.net](https://abhinavsarkar.net) ([Source](https://github.com/abhin4v/abhin4v.github.io/))
- [beautifullhugo theme](https://github.com/halogenica/beautifulhugo) ([Source](https://github.com/halogenica/beautifulhugo/pull/99))
- [blog.jesuislibre.org](http://blog.jesuislibre.org) ([Source](https://github.com/badele/blog.jesuislibre.org))
- [silentcomics.com](https://silentcomics.com) ([Source](https://github.com/SilentComics/silentcomics.github.io/))
- [irz.fr](https://irz.fr) ([Source](https://github.com/arthurlacoste/irz.fr/tree/gh-pages))
- [masterandrey.com](https://masterandrey.com/posts/en/disqus_comments_staticman/)
- [Tyne Time](https://www.tynetime.com) ([Source](https://github.com/Doocey/tyne-time-hugo))
- [BinaryMist](https://binarymist.io/blog) ([Source](https://github.com/binarymist/BinaryMistBlog))
- [La ruta de la cebada](https://larutadelacebada.com) ([Source](https://github.com/lasocial/larutadelacebada.github.io))
- [Gatsby Central](https://www.gatsbycentral.com) ([Source](https://github.com/GatsbyCentral/gatsbycentral.com))

Are you using Staticman? [Let us know!](https://github.com/eduardoboucas/staticman/edit/master/README.md)
44 changes: 43 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,54 @@ const schema = {
default: 'development',
env: 'NODE_ENV'
},
githubAccessTokenUri: {
doc: 'URI for the GitHub authentication provider.',
format: String,
default: 'https://github.com/login/oauth/access_token',
env: 'GITHUB_ACCESS_TOKEN_URI'
},
githubAppID: {
doc: 'ID of the GitHub App.',
format: String,
default: null,
env: 'GITHUB_APP_ID'
},
githubBaseUrl: {
doc: 'Base URL for the GitHub API.',
format: String,
default: 'https://api.github.com',
env: 'GITHUB_BASE_URL'
},
githubPrivateKey: {
doc: 'Private key for the GitHub App.',
format: String,
default: null,
env: 'GITHUB_PRIVATE_KEY'
},
githubToken: {
doc: 'Access token to the GitHub account being used to push files with.',
doc: 'Access token to the GitHub account (legacy)',
format: String,
default: null,
env: 'GITHUB_TOKEN'
},
gitlabAccessTokenUri: {
doc: 'URI for the GitLab authentication provider.',
format: String,
default: 'https://gitlab.com/oauth/token',
env: 'GITLAB_ACCESS_TOKEN_URI'
},
gitlabBaseUrl: {
doc: 'Base URL for the GitLab API.',
format: String,
default: 'https://gitlab.com',
env: 'GITLAB_BASE_URL'
},
gitlabToken: {
doc: 'Access token to the GitLab account being used to push files with.',
format: String,
default: null,
env: 'GITLAB_TOKEN'
},
port: {
doc: 'The port to bind the application to.',
format: 'port',
Expand Down
1 change: 1 addition & 0 deletions config.sample.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"gitlabToken": "YOUR_GITLAB_TOKEN",
"githubToken": "YOUR_GITHUB_TOKEN",
"rsaPrivateKey": "-----BEGIN RSA PRIVATE KEY-----YOUR_KEY-----END RSA PRIVATE KEY-----",
"port": 80
Expand Down
2 changes: 2 additions & 0 deletions config.test.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"gitlabToken": "r4e3w2q1",
"githubToken": "1q2w3e4r",
"rsaPrivateKey": "-----BEGIN RSA PRIVATE KEY-----MIIEpAIBAAKCAQEA2nX81/5w6nZLolEh0uKks3//FlqizKxFWi8GaEJYbud8FYwLH6l+LDfZkjQiDXvm6mxngDGCjlG9b7hgfa/sfWSuqtJUQ2D1Nenn11gwAUaI7OQNSassE+nVFL2BGedl6DOgpZFkKrDTQT7jyvvc3r/2IqWahAYyFWXImD50qwNWIGyZ2Sry2/WXeCydiUWV8ZG3GOlGZLgtlK8igdmLje/6Ja+1oRBFwdbWrf/nKsMB0fCL3R5MkWTnumR8sGx2Xud8Q3mF7cOYWQiy2AqrFQOzJ+QwH6hO6CGVk8eBh8xRkrjaZEsvolZ33N+0aS9NBxHuOyGq0Te9HMLFqwVGzwIDAQABAoIBAQDPD4gAnb0erdMQXT/m50TekdIQuQWXYy00xl+XUFMLg0L8FUmxz++0L5d72Qfxqd97kBYlzkeFZ3pbOvHSD33ieByJ8mNFnc+tMy+4z3BotRcxGRJzIdfcZAS/7MJB8C6KAO0iIQVE5WbGb7pu+XwmcOH1gutKeajc2SVhD8l7ECRARPuV3JxlhbVt+ylM05h7+5HwwnEmodNQHPeGvLEWp7eODNdcLLE5EFVjmN0dwGu9D+xCFna9bL7p921GOTGf349l3021ONaGvWd77Frhl9tHL1k40hqq4LiXDk3RkiP2oDb65+ohW128Q1QPgjMQuXbbFTCa3++pbz7OMbUhAoGBAPxt6A5B3s5GnnaCTE0YJ13aTeUyqrLimBxWEp7L/WXug8SDBW5tVAmBNHlZC4GuR089E7g26BVr0i3k/dOknKa0GLyGGJNphxrrcD05p+XB6Gd6/N1Yr6amM+8XqU1+UKLL2CBrLOSi6r4J4fPS8sb9362+FROwCJZfxd5Wznd/AoGBAN2NEz+anDBgulxLoguGuvc0FaqSsVIP/cdb5Ve5t29/uheVjLgDXSkV5P/RFfk1ygH1gNjmUrsoxfsGWQa3KMTk292maYRj7GPpOalSlp8BYyiQ9omPdOgusVzY4CEjMiDkKal0YrBswXKV8E2lTokEEkbdrQpToVdBmRCzT1ixAoGBAMNMBQ2CyO6ulEr75CyBU3O5QirhWE+uICFMNnvFNvd14VxYQgt9alcwL3jy+4QJYgJcLrWHRWfNU39Oe1MTOF+BVuIEnV7vdifNn7i+srd/nl7xOFHIG53DWMrSc5oQ8DIDo+LxCHqb0SHWY4pQ2qQ6JqQ1O/lPaFVvI5cxcevhAoGALyNtDQNgaAqsnCabe8hWz3INihVcFRHB9UDgMyIYnWiXt5ziK+TLVYqLBsL94eBH8tLBb2TSBXBPb3GST5N44SuwfCCEIt7/1OIymowv7/TjnCX7zpjvTtdgdVjPlz1d1RG2q49P0CnTnwW3801QwGZVXS6dOq1AjsguQRdlsoECgYBrFqKa3S48UbGOKkocgMb/1HzVs2sxNWMu+/jEiBvI4RrCiun9MALtrVtohgHRml4yZJaOojVk9F0z/MAak9eTgSmHpwxYZMqR1PvM4c/ekfun4hQoK04Thoexi/Z0RfsI6nBdBk8MAra03ldDvnYZY4Fat21YuNBspbrbTW8UoA==-----END RSA PRIVATE KEY-----",
"githubPrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA2nX81/5w6nZLolEh0uKks3//FlqizKxFWi8GaEJYbud8FYwLH6l+LDfZkjQiDXvm6mxngDGCjlG9b7hgfa/sfWSuqtJUQ2D1Nenn11gwAUaI7OQNSassE+nVFL2BGedl6DOgpZFkKrDTQT7jyvvc3r/2IqWahAYyFWXImD50qwNWIGyZ2Sry2/WXeCydiUWV8ZG3GOlGZLgtlK8igdmLje/6Ja+1oRBFwdbWrf/nKsMB0fCL3R5MkWTnumR8sGx2Xud8Q3mF7cOYWQiy2AqrFQOzJ+QwH6hO6CGVk8eBh8xRkrjaZEsvolZ33N+0aS9NBxHuOyGq0Te9HMLFqwVGzwIDAQABAoIBAQDPD4gAnb0erdMQXT/m50TekdIQuQWXYy00xl+XUFMLg0L8FUmxz++0L5d72Qfxqd97kBYlzkeFZ3pbOvHSD33ieByJ8mNFnc+tMy+4z3BotRcxGRJzIdfcZAS/7MJB8C6KAO0iIQVE5WbGb7pu+XwmcOH1gutKeajc2SVhD8l7ECRARPuV3JxlhbVt+ylM05h7+5HwwnEmodNQHPeGvLEWp7eODNdcLLE5EFVjmN0dwGu9D+xCFna9bL7p921GOTGf349l3021ONaGvWd77Frhl9tHL1k40hqq4LiXDk3RkiP2oDb65+ohW128Q1QPgjMQuXbbFTCa3++pbz7OMbUhAoGBAPxt6A5B3s5GnnaCTE0YJ13aTeUyqrLimBxWEp7L/WXug8SDBW5tVAmBNHlZC4GuR089E7g26BVr0i3k/dOknKa0GLyGGJNphxrrcD05p+XB6Gd6/N1Yr6amM+8XqU1+UKLL2CBrLOSi6r4J4fPS8sb9362+FROwCJZfxd5Wznd/AoGBAN2NEz+anDBgulxLoguGuvc0FaqSsVIP/cdb5Ve5t29/uheVjLgDXSkV5P/RFfk1ygH1gNjmUrsoxfsGWQa3KMTk292maYRj7GPpOalSlp8BYyiQ9omPdOgusVzY4CEjMiDkKal0YrBswXKV8E2lTokEEkbdrQpToVdBmRCzT1ixAoGBAMNMBQ2CyO6ulEr75CyBU3O5QirhWE+uICFMNnvFNvd14VxYQgt9alcwL3jy+4QJYgJcLrWHRWfNU39Oe1MTOF+BVuIEnV7vdifNn7i+srd/nl7xOFHIG53DWMrSc5oQ8DIDo+LxCHqb0SHWY4pQ2qQ6JqQ1O/lPaFVvI5cxcevhAoGALyNtDQNgaAqsnCabe8hWz3INihVcFRHB9UDgMyIYnWiXt5ziK+TLVYqLBsL94eBH8tLBb2TSBXBPb3GST5N44SuwfCCEIt7/1OIymowv7/TjnCX7zpjvTtdgdVjPlz1d1RG2q49P0CnTnwW3801QwGZVXS6dOq1AjsguQRdlsoECgYBrFqKa3S48UbGOKkocgMb/1HzVs2sxNWMu+/jEiBvI4RrCiun9MALtrVtohgHRml4yZJaOojVk9F0z/MAak9eTgSmHpwxYZMqR1PvM4c/ekfun4hQoK04Thoexi/Z0RfsI6nBdBk8MAra03ldDvnYZY4Fat21YuNBspbrbTW8UoA==\n-----END RSA PRIVATE KEY-----",
"email": {
"apiKey": "key-1q2w3e4r"
},
Expand Down
65 changes: 65 additions & 0 deletions controllers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict'

const gitFactory = require('../lib/GitServiceFactory')
const oauth = require('../lib/OAuth')
const RSA = require('../lib/RSA')
const Staticman = require('../lib/Staticman')

module.exports = (req, res) => {
const staticman = new Staticman(req.params)
staticman.setConfigPath()

let requestAccessToken

switch (req.params.service) {
case 'gitlab':
requestAccessToken = siteConfig =>
oauth.requestGitLabAccessToken(
req.query.code,
siteConfig.get('gitlabAuth.clientId'),
siteConfig.get('gitlabAuth.clientSecret'),
siteConfig.get('gitlabAuth.redirectUri')
)
break
default:
requestAccessToken = siteConfig =>
oauth.requestGitHubAccessToken(
req.query.code,
siteConfig.get('githubAuth.clientId'),
siteConfig.get('githubAuth.clientSecret'),
siteConfig.get('githubAuth.redirectUri')
)
}

return staticman.getSiteConfig()
.then(requestAccessToken)
.then((accessToken) => {
const git = gitFactory.create(req.params.service, {
oauthToken: accessToken,
version: req.params.version
})

// TODO: Simplify this when v2 support is dropped.
const getUser = req.params.version === '2' && req.params.service === 'github'
? git.api.users.getAuthenticated({}).then(({data}) => data)
: git.getCurrentUser()

return getUser
.then((user) => {
res.send({
accessToken: RSA.encrypt(accessToken),
user
})
})
})
.catch((err) => {
console.log('ERR:', err)

const statusCode = err.statusCode || 401

res.status(statusCode).send({
statusCode,
message: err.message
})
})
}
43 changes: 21 additions & 22 deletions controllers/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,39 @@ module.exports = (req, res) => {
const github = new GitHub({
username: req.params.username,
repository: req.params.repository,
branch: req.params.branch
branch: req.params.branch,
token: config.get('githubToken')
})

github.authenticateWithToken(config.get('githubToken'))
return github.api.repos.listInvitationsForAuthenticatedUser({}).then(({data}) => {
let invitationId = null

return github.api.users.getRepoInvites({}).then(response => {
let invitationId

const invitation = response.some(invitation => {
const invitation = Array.isArray(data) && data.some(invitation => {
if (invitation.repository.full_name === (req.params.username + '/' + req.params.repository)) {
invitationId = invitation.id

return true
}
})

if (invitation) {
return github.api.users.acceptRepoInvite({
id: invitationId
})
} else {
res.status(404).send('Invitation not found')
if (!invitation) {
return res.status(404).send('Invitation not found')
}
}).then(response => {
res.send('OK!')

if (ua) {
ua.event('Repositories', 'Connect').send()
}
}).catch(err => { // eslint-disable-line handle-callback-err
res.status(500).send('Error')
return github.api.repos.acceptInvitation({
invitation_id: invitationId
}).then(response => {
res.send('OK!')

if (ua) {
ua.event('Repositories', 'Connect error').send()
}
if (ua) {
ua.event('Repositories', 'Connect').send()
}
}).catch(err => { // eslint-disable-line handle-callback-err
res.status(500).send('Error')

if (ua) {
ua.event('Repositories', 'Connect error').send()
}
})
})
}
32 changes: 0 additions & 32 deletions controllers/githubAuth.js

This file was deleted.

41 changes: 17 additions & 24 deletions controllers/handlePR.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict'

const path = require('path')
const config = require(path.join(__dirname, '/../config'))
const GitHub = require(path.join(__dirname, '/../lib/GitHub'))
const config = require('../config')
const GitHub = require('../lib/GitHub')
const Staticman = require('../lib/Staticman')

module.exports = (repo, data) => {
Expand All @@ -14,45 +13,39 @@ module.exports = (repo, data) => {
return
}

const github = new GitHub()
const github = new GitHub({
username: data.repository.owner.login,
repository: data.repository.name,
token: config.get('githubToken')
})

github.authenticateWithToken(config.get('githubToken'))
return github.getReview(data.number).then((review) => {
if (review.sourceBranch.indexOf('staticman_')) {
return null
}

return github.api.pullRequests.get({
user: data.repository.owner.login,
repo: data.repository.name,
number: data.number
}).then(response => {
if (response.head.ref.indexOf('staticman_')) {
if (review.state !== 'merged' && review.state !== 'closed') {
return null
}

if (response.merged) {
const bodyMatch = response.body.match(/(?:.*?)<!--staticman_notification:(.+?)-->(?:.*?)/i)
if (review.state === 'merged') {
const bodyMatch = review.body.match(/(?:.*?)<!--staticman_notification:(.+?)-->(?:.*?)/i)

if (bodyMatch && (bodyMatch.length === 2)) {
try {
const parsedBody = JSON.parse(bodyMatch[1])
const staticman = new Staticman(parsedBody.parameters)

staticman.authenticate()
staticman.setConfigPath(parsedBody.configPath)
staticman.processMerge(parsedBody.fields, parsedBody.options).catch(err => {
return Promise.reject(err)
})
staticman.processMerge(parsedBody.fields, parsedBody.options)
.catch(err => Promise.reject(err))
} catch (err) {
return Promise.reject(err)
}
}
}

if (response.state === 'closed') {
return github.api.gitdata.deleteReference({
user: data.repository.owner.login,
repo: data.repository.name,
ref: 'heads/' + response.head.ref
})
}
return github.deleteBranch(review.sourceBranch)
}).then(response => {
if (ua) {
ua.event('Hooks', 'Delete branch').send()
Expand Down
Loading

0 comments on commit 2be29f7

Please sign in to comment.