Skip to content
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
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ HackMD
[![version][github-version-badge]][github-release-page]


HackMD lets you create realtime collaborative markdown notes on all platforms.
Inspired by Hackpad, with more focus on speed and flexibility.
HackMD lets you create realtime collaborative markdown notes on all platforms.
Inspired by Hackpad, with more focus on speed and flexibility.
Still in the early stage, feel free to fork or contribute to HackMD.

Thanks for using! :smile:
Expand Down Expand Up @@ -97,13 +97,13 @@ If you are upgrading HackMD from an older version, follow these steps:

* [migration-to-0.5.0](https://github.com/hackmdio/migration-to-0.5.0)

We don't use LZString to compress socket.io data and DB data after version 0.5.0.
We don't use LZString to compress socket.io data and DB data after version 0.5.0.
Please run the migration tool if you're upgrading from the old version.

* [migration-to-0.4.0](https://github.com/hackmdio/migration-to-0.4.0)

We've dropped MongoDB after version 0.4.0.
So here is the migration tool for you to transfer the old DB data to the new DB.
We've dropped MongoDB after version 0.4.0.
So here is the migration tool for you to transfer the old DB data to the new DB.
This tool is also used for official service.

# Configuration
Expand Down Expand Up @@ -141,6 +141,9 @@ There are some configs you need to change in the files below
| HMD_GITLAB_BASEURL | no example | GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional) |
| HMD_GITLAB_CLIENTID | no example | GitLab API client id |
| HMD_GITLAB_CLIENTSECRET | no example | GitLab API client secret |
| HMD_MATTERMOST_BASEURL | no example | Mattermost authentication endpoint |
| HMD_MATTERMOST_CLIENTID | no example | Mattermost API client id |
| HMD_MATTERMOST_CLIENTSECRET | no example | Mattermost API client secret |
| HMD_DROPBOX_CLIENTID | no example | Dropbox API client id |
| HMD_DROPBOX_CLIENTSECRET | no example | Dropbox API client secret |
| HMD_GOOGLE_CLIENTID | no example | Google API client id |
Expand Down Expand Up @@ -216,7 +219,7 @@ There are some configs you need to change in the files below

| service | settings location | description |
| ------- | --------- | ----------- |
| facebook, twitter, github, gitlab, dropbox, google, ldap | environment variables or `config.json` | for signin |
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap | environment variables or `config.json` | for signin |
| imgur | environment variables or `config.json` | for image upload |
| google drive(`google/apiKey`, `google/clientID`), dropbox(`dropbox/appKey`) | `config.json` | for export and import |

Expand All @@ -228,6 +231,7 @@ There are some configs you need to change in the files below
| twitter | `/auth/twitter/callback` |
| github | `/auth/github/callback` |
| gitlab | `/auth/gitlab/callback` |
| mattermost | `/auth/mattermost/callback` |
| dropbox | `/auth/dropbox/callback` |
| google | `/auth/google/callback` |

Expand All @@ -249,9 +253,9 @@ hackmd/

## Operational Transformation

From 0.3.2, we started supporting operational transformation.
It makes concurrent editing safe and will not break up other users' operations.
Additionally, now can show other clients' selections.
From 0.3.2, we started supporting operational transformation.
It makes concurrent editing safe and will not break up other users' operations.
Additionally, now can show other clients' selections.
See more at [http://operational-transformation.github.io/](http://operational-transformation.github.io/)


Expand Down
12 changes: 12 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@
"description": "GitLab API client scope (optional)",
"required": false
},
"HMD_MATTERMOST_BASEURL": {
"description": "Mattermost authentication endpoint",
"required": false
},
"HMD_MATTERMOST_CLIENTID": {
"description": "Mattermost API client id",
"required": false
},
"HMD_MATTERMOST_CLIENTSECRET": {
"description": "Mattermost API client secret",
"required": false
},
"HMD_DROPBOX_CLIENTID": {
"description": "Dropbox API client id",
"required": false
Expand Down
5 changes: 5 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
"clientSecret": "change this",
"scope": "use 'read_user' scope for auth user only or remove this property if you need gitlab snippet import/export support (will result to be default scope 'api')"
},
"mattermost": {
"baseURL": "change this",
"clientID": "change this",
"clientSecret": "change this"
},
"dropbox": {
"clientID": "change this",
"clientSecret": "change this",
Expand Down
5 changes: 5 additions & 0 deletions lib/config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ module.exports = {
clientSecret: undefined,
scope: undefined
},
mattermost: {
baseURL: undefined,
clientID: undefined,
clientSecret: undefined
},
dropbox: {
clientID: undefined,
clientSecret: undefined
Expand Down
4 changes: 4 additions & 0 deletions lib/config/dockerSecret.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ if (fs.existsSync(basePath)) {
clientID: getSecret('gitlab_clientID'),
clientSecret: getSecret('gitlab_clientSecret')
},
mattermost: {
clientID: getSecret('mattermost_clientID'),
clientSecret: getSecret('mattermost_clientSecret')
},
dropbox: {
clientID: getSecret('dropbox_clientID'),
clientSecret: getSecret('dropbox_clientSecret')
Expand Down
5 changes: 5 additions & 0 deletions lib/config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ module.exports = {
clientSecret: process.env.HMD_GITLAB_CLIENTSECRET,
scope: process.env.HMD_GITLAB_SCOPE
},
mattermost: {
baseURL: process.env.HMD_MATTERMOST_BASEURL,
clientID: process.env.HMD_MATTERMOST_CLIENTID,
clientSecret: process.env.HMD_MATTERMOST_CLIENTSECRET
},
dropbox: {
clientID: process.env.HMD_DROPBOX_CLIENTID,
clientSecret: process.env.HMD_DROPBOX_CLIENTSECRET
Expand Down
1 change: 1 addition & 0 deletions lib/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ config.isTwitterEnable = config.twitter.consumerKey && config.twitter.consumerSe
config.isEmailEnable = config.email
config.isGitHubEnable = config.github.clientID && config.github.clientSecret
config.isGitLabEnable = config.gitlab.clientID && config.gitlab.clientSecret
config.isMattermostEnable = config.mattermost.clientID && config.mattermost.clientSecret
config.isLDAPEnable = config.ldap.url
config.isPDFExportEnable = config.allowpdfexport

Expand Down
9 changes: 9 additions & 0 deletions lib/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ module.exports = function (sequelize, DataTypes) {
photo = letterAvatars(profile.username)
}
break
case 'mattermost':
photo = profile.avatarUrl
if (photo) {
if (bigger) photo = photo.replace(/(\?s=)\d*$/i, '$1400')
else photo = photo.replace(/(\?s=)\d*$/i, '$196')
} else {
photo = letterAvatars(profile.username)
}
break
case 'dropbox':
// no image api provided, use gravatar
photo = 'https://www.gravatar.com/avatar/' + md5(profile.emails[0].value)
Expand Down
1 change: 1 addition & 0 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function showIndex (req, res, next) {
twitter: config.isTwitterEnable,
github: config.isGitHubEnable,
gitlab: config.isGitLabEnable,
mattermost: config.isMattermostEnable,
dropbox: config.isDropboxEnable,
google: config.isGoogleEnable,
ldap: config.isLDAPEnable,
Expand Down
1 change: 1 addition & 0 deletions lib/web/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ if (config.isFacebookEnable) authRouter.use(require('./facebook'))
if (config.isTwitterEnable) authRouter.use(require('./twitter'))
if (config.isGitHubEnable) authRouter.use(require('./github'))
if (config.isGitLabEnable) authRouter.use(require('./gitlab'))
if (config.isMattermostEnable) authRouter.use(require('./mattermost'))
if (config.isDropboxEnable) authRouter.use(require('./dropbox'))
if (config.isGoogleEnable) authRouter.use(require('./google'))
if (config.isLDAPEnable) authRouter.use(require('./ldap'))
Expand Down
49 changes: 49 additions & 0 deletions lib/web/auth/mattermost/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict'

const Router = require('express').Router
const passport = require('passport')
const Mattermost = require('mattermost')
const OAuthStrategy = require('passport-oauth2').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')

const mattermost = new Mattermost.Client()

let mattermostAuth = module.exports = Router()

let mattermostStrategy = new OAuthStrategy({
authorizationURL: config.mattermost.baseURL + '/oauth/authorize',
tokenURL: config.mattermost.baseURL + '/oauth/access_token',
clientID: config.mattermost.clientID,
clientSecret: config.mattermost.clientSecret,
callbackURL: config.serverurl + '/auth/mattermost/callback'
}, passportGeneralCallback)

mattermostStrategy.userProfile = (accessToken, done) => {
mattermost.setUrl(config.mattermost.baseURL)
mattermost.token = accessToken
mattermost.useHeaderToken()
mattermost.getMe(
(data) => {
done(null, data)
},
(err) => {
done(err)
}
)
}

passport.use(mattermostStrategy)

mattermostAuth.get('/auth/mattermost', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('oauth2')(req, res, next)
})

// mattermost auth callback
mattermostAuth.get('/auth/mattermost/callback',
passport.authenticate('oauth2', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"markdown-pdf": "^7.0.0",
"mathjax": "~2.7.0",
"mermaid": "~7.1.0",
"mattermost": "^3.4.0",
"meta-marked": "^0.4.2",
"method-override": "^2.3.7",
"moment": "^2.17.1",
Expand All @@ -91,6 +92,7 @@
"passport-google-oauth20": "^1.0.0",
"passport-ldapauth": "^0.6.0",
"passport-local": "^1.0.0",
"passport-oauth2": "^1.4.0",
"passport-twitter": "^1.0.4",
"passport.socketio": "^3.7.0",
"pdfobject": "^2.0.201604172",
Expand Down
4 changes: 2 additions & 2 deletions public/views/index/body.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<% if(allowAnonymous) { %>
<a type="button" href="<%- url %>/new" class="btn btn-sm btn-primary"><i class="fa fa-plus"></i> <%= __('New guest note') %></a>
<% } %>
<% if(facebook || twitter || github || gitlab || dropbox || google || ldap || email) { %>
<% if(facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || email) { %>
<button class="btn btn-sm btn-success ui-signin" data-toggle="modal" data-target=".signin-modal"><%= __('Sign In') %></button>
<% } %>
</div>
Expand Down Expand Up @@ -48,7 +48,7 @@
<% if (errorMessage && errorMessage.length > 0) { %>
<div class="alert alert-danger" style="max-width: 400px; margin: 0 auto;"><%= errorMessage %></div>
<% } %>
<% if(facebook || twitter || github || gitlab || dropbox || google || ldap || email) { %>
<% if(facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || email) { %>
<span class="ui-signin">
<br>
<a type="button" class="btn btn-lg btn-success ui-signin" data-toggle="modal" data-target=".signin-modal" style="min-width: 200px;"><%= __('Sign In') %></a>
Expand Down
9 changes: 7 additions & 2 deletions public/views/shared/signin-modal.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
<i class="fa fa-gitlab"></i> <%= __('Sign in via %s', 'GitLab') %>
</a>
<% } %>
<% if(mattermost) { %>
<a href="<%- url %>/auth/mattermost" class="btn btn-lg btn-block btn-social btn-soundcloud">
<i class="fa fa-mattermost"></i> <%= __('Sign in via %s', 'Mattermost') %>
</a>
<% } %>
<% if(dropbox) { %>
<a href="<%- url %>/auth/dropbox" class="btn btn-lg btn-block btn-social btn-dropbox">
<i class="fa fa-dropbox"></i> <%= __('Sign in via %s', 'Dropbox') %>
Expand All @@ -38,7 +43,7 @@
<i class="fa fa-google"></i> <%= __('Sign in via %s', 'Google') %>
</a>
<% } %>
<% if((facebook || twitter || github || gitlab || dropbox || google) && ldap) { %>
<% if((facebook || twitter || github || gitlab || mattermost || dropbox || google) && ldap) { %>
<hr>
<% }%>
<% if(ldap) { %>
Expand All @@ -63,7 +68,7 @@
</div>
</form>
<% } %>
<% if((facebook || twitter || github || gitlab || dropbox || google || ldap) && email) { %>
<% if((facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap) && email) { %>
<hr>
<% }%>
<% if(email) { %>
Expand Down