From 079822dfecfba659a491034c447c679dab2424c7 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Mon, 9 May 2016 16:27:35 -0400
Subject: Start extending to support GitLab authentication. Add necessary
dependency. Add baseURL parameter for self-hosted GitLab Add necessary
require. Add block for GitLab auth. Fix typo Update font-awesome dependency
for GitLab icon. Use a color closer to GitLab orange. More direct TODO
---
app.js | 17 +++++++++++++++++
bower.json | 2 +-
config.json | 5 +++++
lib/auth.js | 10 ++++++++++
lib/config.js | 2 ++
lib/response.js | 2 ++
package.json | 1 +
public/views/modal.ejs | 5 +++++
8 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/app.js b/app.js
index c3c824a6..a6eded98 100644
--- a/app.js
+++ b/app.js
@@ -292,6 +292,23 @@ if (config.github) {
//github callback actions
app.get('/auth/github/callback/:noteId/:action', response.githubActions);
}
+//gitlab auth
+if (config.gitlab) {
+ app.get('/auth/gitlab',
+ passport.authenticate('gitlab'),
+ function (req, res) {});
+ //gitlab auth callback
+ app.get('/auth/gitlab/callback',
+ passport.authenticate('gitlab', {
+ failureRedirect: config.serverurl
+ }),
+ function (req, res) {
+ res.redirect(config.serverurl);
+ });
+ //gitlab callback actions
+ // TODO: Maybe in the future
+ //app.get('/auth/gitlab/callback/:noteId/:action', response.gitlabActions);
+}
//dropbox auth
if (config.dropbox) {
app.get('/auth/dropbox',
diff --git a/bower.json b/bower.json
index fcc73317..70973750 100644
--- a/bower.json
+++ b/bower.json
@@ -20,7 +20,7 @@
"dependencies": {
"bootstrap": "~3.3.6",
"jquery": "~1.11.3",
- "font-awesome": "~4.5.0",
+ "font-awesome": "~4.6.0",
"Ionicons": "ionicons#~2.0.1",
"reveal.js": "~3.2.0",
"gsap": "greensock#~1.18.0",
diff --git a/config.json b/config.json
index 16ad258b..c65e9c7c 100644
--- a/config.json
+++ b/config.json
@@ -32,6 +32,11 @@
"clientID": "change this",
"clientSecret": "change this"
},
+ "gitlab": {
+ "baseURL": "change this",
+ "clientID": "change this",
+ "clientSecret": "change this"
+ },
"dropbox": {
"clientID": "change this",
"clientSecret": "change this"
diff --git a/lib/auth.js b/lib/auth.js
index af3e8d1d..d495605a 100644
--- a/lib/auth.js
+++ b/lib/auth.js
@@ -4,6 +4,7 @@ var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GithubStrategy = require('passport-github').Strategy;
+var GitlabStrategy = require('passport-gitlab2').Strategy;
var DropboxStrategy = require('passport-dropbox-oauth2').Strategy;
//core
@@ -56,6 +57,15 @@ if (config.github) {
callbackURL: config.serverurl + '/auth/github/callback'
}, callback));
}
+//gitlab
+if (config.gitlab) {
+ passport.use(new GitlabStrategy({
+ baseURL: config.gitlab.baseURL,
+ clientID: config.gitlab.clientID,
+ clientSecret: config.gitlab.clientSecret,
+ callbackURL: config.serverurl + '/auth/gitlab/callback'
+ }, callback));
+}
//dropbox
if (config.dropbox) {
passport.use(new DropboxStrategy({
diff --git a/lib/config.js b/lib/config.js
index 6738d4a8..c138b459 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -59,6 +59,7 @@ var documentmaxlength = config.documentmaxlength || 100000;
var facebook = config.facebook || false;
var twitter = config.twitter || false;
var github = config.github || false;
+var gitlab = config.gitlab || false;
var dropbox = config.dropbox || false;
var imgur = config.imgur || false;
@@ -110,6 +111,7 @@ module.exports = {
facebook: facebook,
twitter: twitter,
github: github,
+ gitlab: gitlab,
dropbox: dropbox,
imgur: imgur
};
\ No newline at end of file
diff --git a/lib/response.js b/lib/response.js
index 7a75e234..2114c99b 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -94,6 +94,7 @@ function showIndex(req, res, next) {
facebook: config.facebook,
twitter: config.twitter,
github: config.github,
+ gitlab: config.gitlab,
dropbox: config.dropbox,
});
res.write(content);
@@ -124,6 +125,7 @@ function responseHackMD(res, note) {
facebook: config.facebook,
twitter: config.twitter,
github: config.github,
+ gitlab: config.gitlab,
dropbox: config.dropbox,
});
var buf = html;
diff --git a/package.json b/package.json
index a70bce31..3ecaa842 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
"passport-dropbox-oauth2": "^1.0.0",
"passport-facebook": "^2.1.0",
"passport-github": "^1.1.0",
+ "passport-gitlab2": "^2.2.0",
"passport-twitter": "^1.0.4",
"passport.socketio": "^3.6.1",
"pg": "^4.5.3",
diff --git a/public/views/modal.ejs b/public/views/modal.ejs
index 260ff423..4eb33bf3 100644
--- a/public/views/modal.ejs
+++ b/public/views/modal.ejs
@@ -28,6 +28,11 @@
Sign in via Dropbox
<% } %>
+ <% if(gitlab) { %>
+
+ Sign in via GitLab
+
+ <% } %>
--
cgit v1.2.3
From 277bf60a2ea539645428360734f9f8d2e33e3631 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Mon, 9 May 2016 17:06:44 -0400
Subject: Add GitLab options.
---
public/views/header.ejs | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/public/views/header.ejs b/public/views/header.ejs
index 40dee0b0..18369ba9 100644
--- a/public/views/header.ejs
+++ b/public/views/header.ejs
@@ -42,6 +42,10 @@
Gist
<% } %>
+ <% if(typeof gitlab !== 'undefined' && gitlab) { %>
+ Snippet
+
+ <% } %>
Dropbox
@@ -50,6 +54,8 @@
Gist
+ Snippet
+
Clipboard
@@ -127,6 +133,10 @@
Gist
<% } %>
+ <% if(typeof gitlab !== 'undefined' && gitlab) { %>
+ Snippet
+
+ <% } %>
Dropbox
@@ -135,6 +145,8 @@
Gist
+ Snippet
+
Clipboard
--
cgit v1.2.3
From 476cabd10952f026f331754baf9846b1aad917cd Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Mon, 9 May 2016 17:07:02 -0400
Subject: Attach to snippet classes.
---
public/js/index.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/public/js/index.js b/public/js/index.js
index 3f0ed593..0b10c9e0 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -496,12 +496,14 @@ var ui = {
export: {
dropbox: $(".ui-save-dropbox"),
googleDrive: $(".ui-save-google-drive"),
- gist: $(".ui-save-gist")
+ gist: $(".ui-save-gist"),
+ snippet: $(".ui-save-snippet")
},
import: {
dropbox: $(".ui-import-dropbox"),
googleDrive: $(".ui-import-google-drive"),
gist: $(".ui-import-gist"),
+ snippet: $(".ui-import-snippet"),
clipboard: $(".ui-import-clipboard")
},
beta: {
--
cgit v1.2.3
From 521f96fb11af9b2669c6d7002f983d3e7cc99e79 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Mon, 9 May 2016 17:07:23 -0400
Subject: Skeletons for GitLab actions.
---
lib/response.js | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/lib/response.js b/lib/response.js
index 2114c99b..63099b8d 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -321,6 +321,17 @@ function actionGist(req, res, note) {
res.redirect("https://github.com/login/oauth/authorize?" + query);
}
+function actionSnippet(req, res, note) {
+ var data = {
+ client_id: config.gitlab.clientID,
+ redirect_uri: config.serverurl + '/auth/github/callback/' + LZString.compressToBase64(note.id) + '/gist',
+ scope: "snippet",
+ state: shortId.generate()
+ };
+ var query = querystring.stringify(data);
+ res.redirect(config.gitlab.baseURL + "/login/oauth/authorize?" + query);
+}
+
function noteActions(req, res, next) {
var noteId = req.params.noteId;
findNote(req, res, function (note) {
@@ -378,6 +389,21 @@ function githubActions(req, res, next) {
});
}
+function gitlabActions(req, res, next) {
+ var noteId = req.params.noteId;
+ findNote(req, res, function (note) {
+ var action = req.params.action;
+ switch (action) {
+ case "gist":
+ gitlabActionSnippet(req, res, note);
+ break;
+ default:
+ res.redirect(config.serverurl + '/' + noteId);
+ break;
+ }
+ });
+}
+
function githubActionGist(req, res, note) {
var code = req.query.code;
var state = req.query.state;
@@ -435,6 +461,63 @@ function githubActionGist(req, res, note) {
}
}
+function gitlabActionSnippet(req, res, note) {
+ var code = req.query.code;
+ var state = req.query.state;
+ if (!code || !state) {
+ return response.errorForbidden(res);
+ } else {
+ var data = {
+ client_id: config.gitlab.clientID,
+ client_secret: config.gitlab.clientSecret,
+ code: code,
+ state: state
+ }
+ var auth_url = config.gitlab.baseURL + '/login/oauth/access_token';
+ request({
+ url: auth_url,
+ method: "POST",
+ json: data
+ }, function (error, httpResponse, body) {
+ if (!error && httpResponse.statusCode == 200) {
+ var access_token = body.access_token;
+ if (access_token) {
+ var content = LZString.decompressFromBase64(note.content);
+ var title = models.Note.decodeTitle(note.title);
+ var filename = title.replace('/', ' ') + '.md';
+ var gist = {
+ "files": {}
+ };
+ gist.files[filename] = {
+ "content": content
+ };
+ var gist_url = "https://api.gitlab.com/snippets";
+ request({
+ url: gist_url,
+ headers: {
+ 'User-Agent': 'HackMD',
+ 'Authorization': 'token ' + access_token
+ },
+ method: "POST",
+ json: gist
+ }, function (error, httpResponse, body) {
+ if (!error && httpResponse.statusCode == 201) {
+ res.setHeader('referer', '');
+ res.redirect(body.html_url);
+ } else {
+ return response.errorForbidden(res);
+ }
+ });
+ } else {
+ return response.errorForbidden(res);
+ }
+ } else {
+ return response.errorForbidden(res);
+ }
+ })
+ }
+}
+
function showPublishSlide(req, res, next) {
findNote(req, res, function (note) {
note.increment('viewcount').then(function (note) {
--
cgit v1.2.3
From 17d2249ec31bce28f79e8def4be1515ac465d29b Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Mon, 9 May 2016 22:37:51 -0400
Subject: Define snippet import modal
---
public/views/body.ejs | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/public/views/body.ejs b/public/views/body.ejs
index 771da880..23a3acef 100644
--- a/public/views/body.ejs
+++ b/public/views/body.ejs
@@ -151,4 +151,24 @@
+
+
<%- include modal %>
\ No newline at end of file
--
cgit v1.2.3
From 70f6e5bc2cbdb15ff48bdf49b09d7c4bb78ea4ba Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Mon, 9 May 2016 22:38:13 -0400
Subject: Define events for snippet actions
---
public/js/index.js | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/public/js/index.js b/public/js/index.js
index 0b10c9e0..17516169 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -1136,6 +1136,8 @@ ui.toolbar.export.googleDrive.click(function (e) {
});
//export to gist
ui.toolbar.export.gist.attr("href", noteurl + "/gist");
+//export to snippet
+ui.toolbar.export.snippet.attr("href", noteurl + "/snippet");
//import from dropbox
ui.toolbar.import.dropbox.click(function () {
var options = {
@@ -1188,6 +1190,10 @@ function buildImportFromGoogleDrive() {
ui.toolbar.import.gist.click(function () {
//na
});
+//import from snippet
+ui.toolbar.import.snippet.click(function () {
+ //na
+});
//import from clipboard
ui.toolbar.import.clipboard.click(function () {
//na
@@ -1355,6 +1361,45 @@ $("#gistImportModalConfirm").click(function () {
}
});
+// snippet import modal
+$("#snippetImportModalClear").click(function () {
+ $("#snippetImportModalContent").val('');
+});
+$("#snippetImportModalConfirm").click(function () {
+ var snippeturl = $("#snippetImportModalContent").val();
+ if (!snippeturl) return;
+ $('#snippetImportModal').modal('hide');
+ $("#snippetImportModalContent").val('');
+ if (!isValidURL(snippeturl)) {
+ showMessageModal(' Import from Snippet', 'Not a valid URL :(', '', '', false);
+ return;
+ } else {
+ // TODO: Validate against config.gitlab.baseURL
+ ui.spinner.show();
+ $.get(snippeturl)
+ .success(function (data) {
+ if (data.files) {
+ var contents = "";
+ Object.keys(data.files).forEach(function (key) {
+ contents += key;
+ contents += '\n---\n';
+ contents += data.files[key].content;
+ contents += '\n\n';
+ });
+ replaceAll(contents);
+ } else {
+ showMessageModal(' Import from Snippet', 'Unable to fetch snippet files :(', '', '', false);
+ }
+ })
+ .error(function (data) {
+ showMessageModal(' Import from Snippet', 'Not a valid Snippet URL :(', '', JSON.stringify(data), false);
+ })
+ .complete(function () {
+ ui.spinner.hide();
+ });
+ }
+});
+
function parseToEditor(data) {
var parsed = toMarkdown(data);
if (parsed)
--
cgit v1.2.3
From a443490ee6257d2e2a5dfabcd9455101c1a5b4c0 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 17:04:45 -0400
Subject: Add accessToken column
---
lib/models/user.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/models/user.js b/lib/models/user.js
index e1a373d6..639fc226 100644
--- a/lib/models/user.js
+++ b/lib/models/user.js
@@ -23,6 +23,9 @@ module.exports = function (sequelize, DataTypes) {
},
history: {
type: DataTypes.TEXT
+ },
+ accessToken: {
+ type: DataTypes.STRING
}
}, {
classMethods: {
@@ -72,6 +75,6 @@ module.exports = function (sequelize, DataTypes) {
}
}
});
-
+
return User;
};
\ No newline at end of file
--
cgit v1.2.3
From 17daf322398c804fa91c08c16c3f48ada4d17b95 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 17:04:55 -0400
Subject: Remove skeleton functions
---
lib/response.js | 83 ---------------------------------------------------------
1 file changed, 83 deletions(-)
diff --git a/lib/response.js b/lib/response.js
index 63099b8d..2114c99b 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -321,17 +321,6 @@ function actionGist(req, res, note) {
res.redirect("https://github.com/login/oauth/authorize?" + query);
}
-function actionSnippet(req, res, note) {
- var data = {
- client_id: config.gitlab.clientID,
- redirect_uri: config.serverurl + '/auth/github/callback/' + LZString.compressToBase64(note.id) + '/gist',
- scope: "snippet",
- state: shortId.generate()
- };
- var query = querystring.stringify(data);
- res.redirect(config.gitlab.baseURL + "/login/oauth/authorize?" + query);
-}
-
function noteActions(req, res, next) {
var noteId = req.params.noteId;
findNote(req, res, function (note) {
@@ -389,21 +378,6 @@ function githubActions(req, res, next) {
});
}
-function gitlabActions(req, res, next) {
- var noteId = req.params.noteId;
- findNote(req, res, function (note) {
- var action = req.params.action;
- switch (action) {
- case "gist":
- gitlabActionSnippet(req, res, note);
- break;
- default:
- res.redirect(config.serverurl + '/' + noteId);
- break;
- }
- });
-}
-
function githubActionGist(req, res, note) {
var code = req.query.code;
var state = req.query.state;
@@ -461,63 +435,6 @@ function githubActionGist(req, res, note) {
}
}
-function gitlabActionSnippet(req, res, note) {
- var code = req.query.code;
- var state = req.query.state;
- if (!code || !state) {
- return response.errorForbidden(res);
- } else {
- var data = {
- client_id: config.gitlab.clientID,
- client_secret: config.gitlab.clientSecret,
- code: code,
- state: state
- }
- var auth_url = config.gitlab.baseURL + '/login/oauth/access_token';
- request({
- url: auth_url,
- method: "POST",
- json: data
- }, function (error, httpResponse, body) {
- if (!error && httpResponse.statusCode == 200) {
- var access_token = body.access_token;
- if (access_token) {
- var content = LZString.decompressFromBase64(note.content);
- var title = models.Note.decodeTitle(note.title);
- var filename = title.replace('/', ' ') + '.md';
- var gist = {
- "files": {}
- };
- gist.files[filename] = {
- "content": content
- };
- var gist_url = "https://api.gitlab.com/snippets";
- request({
- url: gist_url,
- headers: {
- 'User-Agent': 'HackMD',
- 'Authorization': 'token ' + access_token
- },
- method: "POST",
- json: gist
- }, function (error, httpResponse, body) {
- if (!error && httpResponse.statusCode == 201) {
- res.setHeader('referer', '');
- res.redirect(body.html_url);
- } else {
- return response.errorForbidden(res);
- }
- });
- } else {
- return response.errorForbidden(res);
- }
- } else {
- return response.errorForbidden(res);
- }
- })
- }
-}
-
function showPublishSlide(req, res, next) {
findNote(req, res, function (note) {
note.increment('viewcount').then(function (note) {
--
cgit v1.2.3
From 3dd3e6bc3596c0bba50dca3d1789f55883e0f681 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 17:05:25 -0400
Subject: Allow importing from GitLab snippet
---
public/js/index.js | 69 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 21 deletions(-)
diff --git a/public/js/index.js b/public/js/index.js
index 17516169..7b22f7fa 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -243,6 +243,15 @@ var lastInfo = {
};
var personalInfo = {};
var onlineUsers = [];
+var fileTypes = {
+ "pl": "perl",
+ "cgi": "perl",
+ "js": "javascript",
+ "php": "php",
+ "sh": "bash",
+ "rb": "ruby",
+ "html": "html"
+}
//editor settings
var textit = document.getElementById("textit");
@@ -1192,7 +1201,22 @@ ui.toolbar.import.gist.click(function () {
});
//import from snippet
ui.toolbar.import.snippet.click(function () {
- //na
+ $.get(serverurl + '/gitlab')
+ .success(function (data) {
+ $("#snippetImportModalAccessToken").val(data.accesstoken);
+ $("#snippetImportModalBaseURL").val(data.baseURL);
+ $("#snippetImportModalContent").prop('disabled', false);
+ $("#snippetImportModalConfirm").prop('disabled', false);
+ $("#snippetImportModalLoading").hide();
+ $("#snippetImportModal").modal('toggle');
+ })
+ .error(function (data) {
+ showMessageModal(' Import from Snippet', 'Unable to fetch gitlab parameters :(', '', '', false);
+ })
+ .complete(function () {
+ //na
+ });
+ return false;
});
//import from clipboard
ui.toolbar.import.clipboard.click(function () {
@@ -1370,32 +1394,35 @@ $("#snippetImportModalConfirm").click(function () {
if (!snippeturl) return;
$('#snippetImportModal').modal('hide');
$("#snippetImportModalContent").val('');
- if (!isValidURL(snippeturl)) {
- showMessageModal(' Import from Snippet', 'Not a valid URL :(', '', '', false);
- return;
+ if (!/^.+\/snippets\/.+$/.test(snippeturl)) {
+ showMessageModal(' Import from Snippet', 'Not a valid Snippet URL :(', '', '', false);
} else {
- // TODO: Validate against config.gitlab.baseURL
ui.spinner.show();
- $.get(snippeturl)
- .success(function (data) {
- if (data.files) {
- var contents = "";
- Object.keys(data.files).forEach(function (key) {
- contents += key;
- contents += '\n---\n';
- contents += data.files[key].content;
- contents += '\n\n';
+ var accessToken = '?access_token=' + $("#snippetImportModalAccessToken").val();
+ var fullURL = $("#snippetImportModalBaseURL").val() + '/api/v3' + snippeturl;
+ $.get(fullURL + accessToken)
+ .success(function(data) {
+ var content = '# ' + (data.title || "Snippet Import");
+ var fileInfo = data.file_name.split('.');
+ $.get(fullURL + '/raw' + accessToken)
+ .success(function (raw) {
+ if (raw) {
+ content += "\n\n```";
+ content += fileTypes[fileInfo[1]] + "=\n";
+ content += raw;
+ content += "\n```";
+ replaceAll(content);
+ }
+ })
+ .error(function (data) {
+ showMessageModal(' Import from Snippet', 'Not a valid Snippet URL :(', '', JSON.stringify(data), false);
+ })
+ .complete(function () {
+ ui.spinner.hide();
});
- replaceAll(contents);
- } else {
- showMessageModal(' Import from Snippet', 'Unable to fetch snippet files :(', '', '', false);
- }
})
.error(function (data) {
showMessageModal(' Import from Snippet', 'Not a valid Snippet URL :(', '', JSON.stringify(data), false);
- })
- .complete(function () {
- ui.spinner.hide();
});
}
});
--
cgit v1.2.3
From 9f401b3fa88aa60c435c548f807fbb0742aaa2e0 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 17:05:53 -0400
Subject: Fully-fleshed snippetImportModal
---
public/views/body.ejs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/public/views/body.ejs b/public/views/body.ejs
index 23a3acef..039690ef 100644
--- a/public/views/body.ejs
+++ b/public/views/body.ejs
@@ -158,15 +158,17 @@
-
+
+
+
--
cgit v1.2.3
From e545de72a6daab8f51d4b39ec9e33563eb16ee68 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 17:06:05 -0400
Subject: Add accessToken saving.
---
lib/auth.js | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/lib/auth.js b/lib/auth.js
index d495605a..ec45eea3 100644
--- a/lib/auth.js
+++ b/lib/auth.js
@@ -19,13 +19,23 @@ function callback(accessToken, refreshToken, profile, done) {
profileid: profile.id.toString()
},
defaults: {
- profile: JSON.stringify(profile)
+ profile: JSON.stringify(profile),
+ accessToken: accessToken,
+ refreshToken: refreshToken
}
}).spread(function(user, created) {
if (user) {
- if (config.debug)
- logger.info('user login: ' + user.id);
- return done(null, user);
+ if(user.accessToken == accessToken){
+ if (config.debug)
+ logger.info('user login: ' + user.id);
+ return done(null, user);
+ }
+ user.accessToken = accessToken;
+ user.save().then(function(){
+ if (config.debug)
+ logger.info('user login: ' + user.id);
+ return done(null, user);
+ })
}
}).catch(function(err) {
logger.error('auth callback failed: ' + err);
--
cgit v1.2.3
From ad79b581bda79ef2be0d6ad1a192fc7d0afef2f0 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 17:06:18 -0400
Subject: End-point to get GitLab data.
---
app.js | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/app.js b/app.js
index a6eded98..964a3a81 100644
--- a/app.js
+++ b/app.js
@@ -16,6 +16,7 @@ var formidable = require('formidable');
var morgan = require('morgan');
var passportSocketIo = require("passport.socketio");
var helmet = require('helmet');
+var request = require('request');
//core
var config = require("./lib/config.js");
@@ -82,6 +83,9 @@ var sessionStore = new SequelizeStore({
//compression
app.use(compression());
+//cookies
+app.use(cookieParser());
+
// use hsts to tell https users stick to this
app.use(helmet.hsts({
maxAge: 31536000 * 1000, // 365 days
@@ -438,6 +442,18 @@ app.post('/uploadimage', function (req, res) {
}
});
});
+//get gitlab parameters
+app.get('/gitlab', function (req, res) {
+ var ret = { baseURL: config.gitlab.baseURL };
+ models.User.findById(req.cookies.userid)
+ .then(function(user) {
+ ret.accesstoken = user.accessToken;
+ return res.send(ret);
+ }).catch(function(err) {
+ logger.error('user search failed: ' + err);
+ return done(err, null);
+ });
+});
//get new note
app.get("/new", response.newNote);
//get publish note
--
cgit v1.2.3
From de998c4a0fcbadc4c0353c8e65d5769c271cfcd9 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Wed, 11 May 2016 21:12:48 -0400
Subject: Check to make sure GitLab is configured before showing import option.
---
public/views/header.ejs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/public/views/header.ejs b/public/views/header.ejs
index 18369ba9..051817dc 100644
--- a/public/views/header.ejs
+++ b/public/views/header.ejs
@@ -54,8 +54,10 @@
Gist
+ <% if(typeof gitlab !== 'undefined' && gitlab) { %>
Snippet
+ <% } %>
Clipboard
@@ -145,8 +147,10 @@
Gist
+ <% if(typeof gitlab !== 'undefined' && gitlab) { %>
Snippet
+ <% } %>
Clipboard
--
cgit v1.2.3
From c16345ab128288b92023e789f09cabb5197d1181 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Thu, 12 May 2016 11:19:14 -0400
Subject: Can now select from available projects and snippets to build import
URL.
---
app.js | 14 ++++++++++++--
public/css/index.css | 5 +++++
public/js/index.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
public/views/body.ejs | 20 ++++++++++++++++++--
4 files changed, 86 insertions(+), 4 deletions(-)
diff --git a/app.js b/app.js
index 964a3a81..60eb61b5 100644
--- a/app.js
+++ b/app.js
@@ -448,10 +448,20 @@ app.get('/gitlab', function (req, res) {
models.User.findById(req.cookies.userid)
.then(function(user) {
ret.accesstoken = user.accessToken;
- return res.send(ret);
+ request(
+ config.gitlab.baseURL + '/api/v3/projects?access_token=' + user.accessToken,
+ function(error, httpResponse, body) {
+ if (!error && httpResponse.statusCode == 200) {
+ ret.projects = JSON.parse(body);
+ return res.send(ret);
+ } else {
+ return res.send(ret);
+ }
+ }
+ );
}).catch(function(err) {
logger.error('user search failed: ' + err);
- return done(err, null);
+ return response.errorInternalError(res);
});
});
//get new note
diff --git a/public/css/index.css b/public/css/index.css
index fdfae0ac..aaf84a04 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -328,6 +328,11 @@ div[contenteditable]:empty:not(:focus):before{
border-bottom: 1px solid #ccc;
}
+.snippet-import-or {
+ text-align: center;
+ width: 100%;
+}
+
.status-bar {
background: #1c1c1e;
border-top: 1px solid #343434;
diff --git a/public/js/index.js b/public/js/index.js
index 7b22f7fa..199c678e 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -552,6 +552,10 @@ var ui = {
codemirrorSizer: $(".ui-edit-area .CodeMirror .CodeMirror-sizer"),
codemirrorSizerInner: $(".ui-edit-area .CodeMirror .CodeMirror-sizer > div"),
markdown: $(".ui-view-area .markdown-body")
+ },
+ modal: {
+ snippetProjects: $("#snippetImportModalProjects"),
+ snippetSnippets: $("#snippetImportModalSnippets")
}
};
@@ -1209,6 +1213,17 @@ ui.toolbar.import.snippet.click(function () {
$("#snippetImportModalConfirm").prop('disabled', false);
$("#snippetImportModalLoading").hide();
$("#snippetImportModal").modal('toggle');
+ $("#snippetImportModalProjects").find('option').remove().end().append('');
+ if (data.projects) {
+ data.projects.sort(function(a,b) {
+ return (a.path_with_namespace < b.path_with_namespace) ? -1 : ((a.path_with_namespace > b.path_with_namespace) ? 1 : 0);
+ });
+ data.projects.forEach(function(project) {
+ $('');
+ data.forEach(function(snippet) {
+ $('').val(project.id).text(project.path_with_namespace).appendTo("#snippetExportModalProjects");
});
$("#snippetExportModalProjects").prop('disabled',false);
--
cgit v1.2.3
From edcb766b63694948b91094995ca7720c1ea222c3 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Fri, 13 May 2016 10:00:34 -0400
Subject: Apply "snippets_enabled only" logic to import modal. Better parsing
for snippet import. Add python filetype.
---
public/js/index.js | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/public/js/index.js b/public/js/index.js
index fbaf95fb..a1e0445b 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -250,8 +250,9 @@ var fileTypes = {
"php": "php",
"sh": "bash",
"rb": "ruby",
- "html": "html"
-}
+ "html": "html",
+ "py": "python"
+};
//editor settings
var textit = document.getElementById("textit");
@@ -1248,6 +1249,9 @@ ui.toolbar.import.snippet.click(function () {
return (a.path_with_namespace < b.path_with_namespace) ? -1 : ((a.path_with_namespace > b.path_with_namespace) ? 1 : 0);
});
data.projects.forEach(function(project) {
+ if (!project.snippets_enabled) {
+ return;
+ }
$('').val(project.id).text(project.path_with_namespace).appendTo("#snippetImportModalProjects");
});
$("#snippetImportModalProjects").prop('disabled',false);
@@ -1484,13 +1488,18 @@ $("#snippetImportModalConfirm").click(function () {
.success(function(data) {
var content = '# ' + (data.title || "Snippet Import");
var fileInfo = data.file_name.split('.');
+ fileInfo[1] = (fileInfo[1]) ? fileInfo[1] : "md";
$.get(fullURL + '/raw' + accessToken)
.success(function (raw) {
if (raw) {
- content += "\n\n```";
- content += fileTypes[fileInfo[1]] + "=\n";
+ content += "\n\n";
+ if (fileInfo[1] != "md") {
+ content += "```" + fileTypes[fileInfo[1]] + "\n";
+ }
content += raw;
- content += "\n```";
+ if (fileInfo[1] != "md") {
+ content += "\n```";
+ }
replaceAll(content);
}
})
--
cgit v1.2.3
From 930afdc33738a487bd9e596c5d35bc9f686eaaa1 Mon Sep 17 00:00:00 2001
From: Jason Croft
Date: Fri, 13 May 2016 10:32:30 -0400
Subject: Show only projects where user is creator, has project access >= 20,
or has group access.
---
app.js | 1 +
public/js/index.js | 10 ++++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/app.js b/app.js
index 5d847f76..35408bb0 100644
--- a/app.js
+++ b/app.js
@@ -448,6 +448,7 @@ app.get('/gitlab', function (req, res) {
models.User.findById(req.cookies.userid)
.then(function(user) {
ret.accesstoken = user.accessToken;
+ ret.profileid = user.profileid;
request(
config.gitlab.baseURL + '/api/v3/projects?access_token=' + user.accessToken,
function(error, httpResponse, body) {
diff --git a/public/js/index.js b/public/js/index.js
index a1e0445b..7e692bee 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -1164,7 +1164,10 @@ ui.toolbar.export.snippet.click(function() {
return (a.path_with_namespace < b.path_with_namespace) ? -1 : ((a.path_with_namespace > b.path_with_namespace) ? 1 : 0);
});
data.projects.forEach(function(project) {
- if (!project.snippets_enabled) {
+ if (!project.snippets_enabled
+ || (project.permissions.project_access === null && project.permissions.group_access === null)
+ || (project.permissions.project_access !== null && project.permissions.project_access.access_level < 20))
+ {
return;
}
$('').val(project.id).text(project.path_with_namespace).appendTo("#snippetExportModalProjects");
@@ -1249,7 +1252,10 @@ ui.toolbar.import.snippet.click(function () {
return (a.path_with_namespace < b.path_with_namespace) ? -1 : ((a.path_with_namespace > b.path_with_namespace) ? 1 : 0);
});
data.projects.forEach(function(project) {
- if (!project.snippets_enabled) {
+ if (!project.snippets_enabled
+ || (project.permissions.project_access === null && project.permissions.group_access === null)
+ || (project.permissions.project_access !== null && project.permissions.project_access.access_level < 20))
+ {
return;
}
$('').val(project.id).text(project.path_with_namespace).appendTo("#snippetImportModalProjects");
--
cgit v1.2.3