Skip to content

Commit 8a01b72

Browse files
committed
Merge branch 'gitlab_snippets' of https://github.com/jccrofty30/hackmd into jccrofty30-gitlab_snippets
# Conflicts: # lib/response.js
2 parents 22f7c4b + 930afdc commit 8a01b72

8 files changed

Lines changed: 348 additions & 6 deletions

File tree

app.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var formidable = require('formidable');
1616
var morgan = require('morgan');
1717
var passportSocketIo = require("passport.socketio");
1818
var helmet = require('helmet');
19+
var request = require('request');
1920

2021
//core
2122
var config = require("./lib/config.js");
@@ -82,6 +83,9 @@ var sessionStore = new SequelizeStore({
8283
//compression
8384
app.use(compression());
8485

86+
//cookies
87+
app.use(cookieParser());
88+
8589
// use hsts to tell https users stick to this
8690
app.use(helmet.hsts({
8791
maxAge: 31536000 * 1000, // 365 days
@@ -438,6 +442,29 @@ app.post('/uploadimage', function (req, res) {
438442
}
439443
});
440444
});
445+
//get gitlab parameters
446+
app.get('/gitlab', function (req, res) {
447+
var ret = { baseURL: config.gitlab.baseURL };
448+
models.User.findById(req.cookies.userid)
449+
.then(function(user) {
450+
ret.accesstoken = user.accessToken;
451+
ret.profileid = user.profileid;
452+
request(
453+
config.gitlab.baseURL + '/api/v3/projects?access_token=' + user.accessToken,
454+
function(error, httpResponse, body) {
455+
if (!error && httpResponse.statusCode == 200) {
456+
ret.projects = JSON.parse(body);
457+
return res.send(ret);
458+
} else {
459+
return res.send(ret);
460+
}
461+
}
462+
);
463+
}).catch(function(err) {
464+
logger.error('user search failed: ' + err);
465+
return response.errorInternalError(res);
466+
});
467+
});
441468
//get new note
442469
app.get("/new", response.newNote);
443470
//get publish note

lib/auth.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,23 @@ function callback(accessToken, refreshToken, profile, done) {
1919
profileid: profile.id.toString()
2020
},
2121
defaults: {
22-
profile: JSON.stringify(profile)
22+
profile: JSON.stringify(profile),
23+
accessToken: accessToken,
24+
refreshToken: refreshToken
2325
}
2426
}).spread(function(user, created) {
2527
if (user) {
26-
if (config.debug)
27-
logger.info('user login: ' + user.id);
28-
return done(null, user);
28+
if(user.accessToken == accessToken){
29+
if (config.debug)
30+
logger.info('user login: ' + user.id);
31+
return done(null, user);
32+
}
33+
user.accessToken = accessToken;
34+
user.save().then(function(){
35+
if (config.debug)
36+
logger.info('user login: ' + user.id);
37+
return done(null, user);
38+
})
2939
}
3040
}).catch(function(err) {
3141
logger.error('auth callback failed: ' + err);

lib/models/user.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ module.exports = function (sequelize, DataTypes) {
2323
},
2424
history: {
2525
type: DataTypes.TEXT
26+
},
27+
accessToken: {
28+
type: DataTypes.STRING
2629
}
2730
}, {
2831
classMethods: {
@@ -75,6 +78,6 @@ module.exports = function (sequelize, DataTypes) {
7578
}
7679
}
7780
});
78-
81+
7982
return User;
8083
};

lib/response.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,11 @@ function responseHackMD(res, note) {
126126
twitter: config.twitter,
127127
github: config.github,
128128
gitlab: config.gitlab,
129+
<<<<<<< HEAD
129130
dropbox: config.dropbox
131+
=======
132+
dropbox: config.dropbox,
133+
>>>>>>> 930afdc33738a487bd9e596c5d35bc9f686eaaa1
130134
});
131135
var buf = html;
132136
res.writeHead(200, {

public/css/index.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,11 @@ div[contenteditable]:empty:not(:focus):before{
328328
border-bottom: 1px solid #ccc;
329329
}
330330

331+
.snippet-import-or {
332+
text-align: center;
333+
width: 100%;
334+
}
335+
331336
.status-bar {
332337
background: #1c1c1e;
333338
border-top: 1px solid #343434;

public/js/index.js

Lines changed: 195 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ var lastInfo = {
243243
};
244244
var personalInfo = {};
245245
var onlineUsers = [];
246+
var fileTypes = {
247+
"pl": "perl",
248+
"cgi": "perl",
249+
"js": "javascript",
250+
"php": "php",
251+
"sh": "bash",
252+
"rb": "ruby",
253+
"html": "html",
254+
"py": "python"
255+
};
246256

247257
//editor settings
248258
var textit = document.getElementById("textit");
@@ -496,12 +506,14 @@ var ui = {
496506
export: {
497507
dropbox: $(".ui-save-dropbox"),
498508
googleDrive: $(".ui-save-google-drive"),
499-
gist: $(".ui-save-gist")
509+
gist: $(".ui-save-gist"),
510+
snippet: $(".ui-save-snippet")
500511
},
501512
import: {
502513
dropbox: $(".ui-import-dropbox"),
503514
googleDrive: $(".ui-import-google-drive"),
504515
gist: $(".ui-import-gist"),
516+
snippet: $(".ui-import-snippet"),
505517
clipboard: $(".ui-import-clipboard")
506518
},
507519
beta: {
@@ -541,6 +553,10 @@ var ui = {
541553
codemirrorSizer: $(".ui-edit-area .CodeMirror .CodeMirror-sizer"),
542554
codemirrorSizerInner: $(".ui-edit-area .CodeMirror .CodeMirror-sizer > div"),
543555
markdown: $(".ui-view-area .markdown-body")
556+
},
557+
modal: {
558+
snippetImportProjects: $("#snippetImportModalProjects"),
559+
snippetImportSnippets: $("#snippetImportModalSnippets")
544560
}
545561
};
546562

@@ -1163,6 +1179,40 @@ ui.toolbar.export.googleDrive.click(function (e) {
11631179
});
11641180
//export to gist
11651181
ui.toolbar.export.gist.attr("href", noteurl + "/gist");
1182+
//export to snippet
1183+
ui.toolbar.export.snippet.click(function() {
1184+
$.get(serverurl + '/gitlab')
1185+
.success(function (data) {
1186+
$("#snippetExportModalAccessToken").val(data.accesstoken);
1187+
$("#snippetExportModalBaseURL").val(data.baseURL);
1188+
$("#snippetExportModalLoading").hide();
1189+
$("#snippetExportModal").modal('toggle');
1190+
$("#snippetExportModalProjects").find('option').remove().end().append('<option value="init" selected="selected" disabled="disabled">Select From Available Projects</option>');
1191+
if (data.projects) {
1192+
data.projects.sort(function(a,b) {
1193+
return (a.path_with_namespace < b.path_with_namespace) ? -1 : ((a.path_with_namespace > b.path_with_namespace) ? 1 : 0);
1194+
});
1195+
data.projects.forEach(function(project) {
1196+
if (!project.snippets_enabled
1197+
|| (project.permissions.project_access === null && project.permissions.group_access === null)
1198+
|| (project.permissions.project_access !== null && project.permissions.project_access.access_level < 20))
1199+
{
1200+
return;
1201+
}
1202+
$('<option>').val(project.id).text(project.path_with_namespace).appendTo("#snippetExportModalProjects");
1203+
});
1204+
$("#snippetExportModalProjects").prop('disabled',false);
1205+
}
1206+
$("#snippetExportModalLoading").hide();
1207+
})
1208+
.error(function (data) {
1209+
showMessageModal('<i class="fa fa-gitlab"></i> Import from Snippet', 'Unable to fetch gitlab parameters :(', '', '', false);
1210+
})
1211+
.complete(function () {
1212+
//na
1213+
});
1214+
return false;
1215+
});
11661216
//import from dropbox
11671217
ui.toolbar.import.dropbox.click(function () {
11681218
var options = {
@@ -1215,6 +1265,42 @@ function buildImportFromGoogleDrive() {
12151265
ui.toolbar.import.gist.click(function () {
12161266
//na
12171267
});
1268+
//import from snippet
1269+
ui.toolbar.import.snippet.click(function () {
1270+
$.get(serverurl + '/gitlab')
1271+
.success(function (data) {
1272+
$("#snippetImportModalAccessToken").val(data.accesstoken);
1273+
$("#snippetImportModalBaseURL").val(data.baseURL);
1274+
$("#snippetImportModalContent").prop('disabled', false);
1275+
$("#snippetImportModalConfirm").prop('disabled', false);
1276+
$("#snippetImportModalLoading").hide();
1277+
$("#snippetImportModal").modal('toggle');
1278+
$("#snippetImportModalProjects").find('option').remove().end().append('<option value="init" selected="selected" disabled="disabled">Select From Available Projects</option>');
1279+
if (data.projects) {
1280+
data.projects.sort(function(a,b) {
1281+
return (a.path_with_namespace < b.path_with_namespace) ? -1 : ((a.path_with_namespace > b.path_with_namespace) ? 1 : 0);
1282+
});
1283+
data.projects.forEach(function(project) {
1284+
if (!project.snippets_enabled
1285+
|| (project.permissions.project_access === null && project.permissions.group_access === null)
1286+
|| (project.permissions.project_access !== null && project.permissions.project_access.access_level < 20))
1287+
{
1288+
return;
1289+
}
1290+
$('<option>').val(project.id).text(project.path_with_namespace).appendTo("#snippetImportModalProjects");
1291+
});
1292+
$("#snippetImportModalProjects").prop('disabled',false);
1293+
}
1294+
$("#snippetImportModalLoading").hide();
1295+
})
1296+
.error(function (data) {
1297+
showMessageModal('<i class="fa fa-gitlab"></i> Import from Snippet', 'Unable to fetch gitlab parameters :(', '', '', false);
1298+
})
1299+
.complete(function () {
1300+
//na
1301+
});
1302+
return false;
1303+
});
12181304
//import from clipboard
12191305
ui.toolbar.import.clipboard.click(function () {
12201306
//na
@@ -1236,6 +1322,39 @@ ui.toolbar.beta.pdf.attr("download", "").attr("href", noteurl + "/pdf");
12361322
//slide
12371323
ui.toolbar.beta.slide.attr("href", noteurl + "/slide");
12381324

1325+
//modal actions
1326+
//snippet projects
1327+
ui.modal.snippetImportProjects.change(function() {
1328+
var accesstoken = $("#snippetImportModalAccessToken").val(),
1329+
baseURL = $("#snippetImportModalBaseURL").val(),
1330+
project = $("#snippetImportModalProjects").val();
1331+
1332+
$("#snippetImportModalLoading").show();
1333+
$("#snippetImportModalContent").val('/projects/' + project);
1334+
$.get(baseURL + '/api/v3/projects/' + project + '/snippets?access_token=' + accesstoken)
1335+
.success(function(data) {
1336+
$("#snippetImportModalSnippets").find('option').remove().end().append('<option value="init" selected="selected" disabled="disabled">Select From Available Snippets</option>');
1337+
data.forEach(function(snippet) {
1338+
$('<option>').val(snippet.id).text(snippet.title).appendTo($("#snippetImportModalSnippets"));
1339+
});
1340+
$("#snippetImportModalLoading").hide();
1341+
$("#snippetImportModalSnippets").prop('disabled',false);
1342+
})
1343+
.error(function(err) {
1344+
1345+
})
1346+
.complete(function() {
1347+
//na
1348+
});
1349+
});
1350+
//snippet snippets
1351+
ui.modal.snippetImportSnippets.change(function() {
1352+
var project = $("#snippetImportModalProjects").val(),
1353+
snippet = $("#snippetImportModalSnippets").val();
1354+
1355+
$("#snippetImportModalContent").val($("#snippetImportModalContent").val() + '/snippets/' + snippet);
1356+
})
1357+
12391358
function scrollToTop() {
12401359
if (currentMode == modeType.both) {
12411360
if (editor.getScrollInfo().top != 0)
@@ -1382,6 +1501,81 @@ $("#gistImportModalConfirm").click(function () {
13821501
}
13831502
});
13841503

1504+
// snippet import modal
1505+
$("#snippetImportModalClear").click(function () {
1506+
$("#snippetImportModalContent").val('');
1507+
$("#snippetImportModalProjects").val('init');
1508+
$("#snippetImportModalSnippets").val('init');
1509+
$("#snippetImportModalSnippets").prop('disabled',true);
1510+
});
1511+
$("#snippetImportModalConfirm").click(function () {
1512+
var snippeturl = $("#snippetImportModalContent").val();
1513+
if (!snippeturl) return;
1514+
$('#snippetImportModal').modal('hide');
1515+
$("#snippetImportModalContent").val('');
1516+
if (!/^.+\/snippets\/.+$/.test(snippeturl)) {
1517+
showMessageModal('<i class="fa fa-github"></i> Import from Snippet', 'Not a valid Snippet URL :(', '', '', false);
1518+
} else {
1519+
ui.spinner.show();
1520+
var accessToken = '?access_token=' + $("#snippetImportModalAccessToken").val();
1521+
var fullURL = $("#snippetImportModalBaseURL").val() + '/api/v3' + snippeturl;
1522+
$.get(fullURL + accessToken)
1523+
.success(function(data) {
1524+
var content = '# ' + (data.title || "Snippet Import");
1525+
var fileInfo = data.file_name.split('.');
1526+
fileInfo[1] = (fileInfo[1]) ? fileInfo[1] : "md";
1527+
$.get(fullURL + '/raw' + accessToken)
1528+
.success(function (raw) {
1529+
if (raw) {
1530+
content += "\n\n";
1531+
if (fileInfo[1] != "md") {
1532+
content += "```" + fileTypes[fileInfo[1]] + "\n";
1533+
}
1534+
content += raw;
1535+
if (fileInfo[1] != "md") {
1536+
content += "\n```";
1537+
}
1538+
replaceAll(content);
1539+
}
1540+
})
1541+
.error(function (data) {
1542+
showMessageModal('<i class="fa fa-gitlab"></i> Import from Snippet', 'Not a valid Snippet URL :(', '', JSON.stringify(data), false);
1543+
})
1544+
.complete(function () {
1545+
ui.spinner.hide();
1546+
});
1547+
})
1548+
.error(function (data) {
1549+
showMessageModal('<i class="fa fa-gitlab"></i> Import from Snippet', 'Not a valid Snippet URL :(', '', JSON.stringify(data), false);
1550+
});
1551+
}
1552+
});
1553+
1554+
//snippet export modal
1555+
$("#snippetExportModalConfirm").click(function() {
1556+
var accesstoken = $("#snippetExportModalAccessToken").val(),
1557+
baseURL = $("#snippetExportModalBaseURL").val(),
1558+
data = {
1559+
title: $("#snippetExportModalTitle").val(),
1560+
file_name: $("#snippetExportModalFileName").val(),
1561+
code: editor.getValue(),
1562+
visibility_level: $("#snippetExportModalVisibility").val()
1563+
};
1564+
1565+
$("#snippetExportModalLoading").show();
1566+
var fullURL = baseURL + '/api/v3/projects/' + $("#snippetExportModalProjects").val() + '/snippets?access_token=' + accesstoken;
1567+
$.post(fullURL
1568+
, data
1569+
, function(ret) {
1570+
$("#snippetExportModalLoading").hide();
1571+
$('#snippetExportModal').modal('hide');
1572+
var redirect = baseURL + '/' + $("#snippetExportModalProjects option[value='" + $("#snippetExportModalProjects").val() + "']").text() + '/snippets/' + ret.id;
1573+
showMessageModal('<i class="fa fa-gitlab"></i> Export to Snippet', 'Export Successful!', redirect, 'View Snippet Here', true);
1574+
}
1575+
, 'json'
1576+
);
1577+
});
1578+
13851579
function parseToEditor(data) {
13861580
var parsed = toMarkdown(data);
13871581
if (parsed)

0 commit comments

Comments
 (0)