Skip to content

Commit b59ccca

Browse files
authored
Merge pull request #180 from ksraj123/feature-wikis
Feature wikis
2 parents 3720eee + a8b673a commit b59ccca

File tree

10 files changed

+442
-1
lines changed

10 files changed

+442
-1
lines changed

.env.dev

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ JWT_SECRET="thisismysupersecrettokenjustkidding"
44
DATABASE_URL="mongodb://mongo:27017/donut-development"
55
SENDGRID_API_KEY='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'
66
SOCKET_PORT=8810
7-
clientbaseurl = "http://localhost:3000"
7+
clientbaseurl="http://localhost:3000"
88
SOCKET_PORT=8810
99
REDIS_HOST="redis"
1010
REDIS_PORT=6379
1111
REDIS_PASSWORD="auth"
1212
REDIS_DB=0
1313
REDIS_ACTIVITY_DB=1
14+
GITHUB_OAUTH_APP_CLIENTID="a3e08516c35fe7e83f43"
15+
GITHUB_OAUTH_APP_CLIENTSECRET="8393d95c3bfeeb0943045f447a9d055cb660bce0"

app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const projectRouter = require('./app/routes/project')
2727
const notificationRouter = require('./app/routes/notification')
2828
const proposalRouter = require('./app/routes/proposal')
2929
const analyticsRouter = require('./app/routes/analytics')
30+
const wikisRouter = require('./app/routes/wikis')
3031
const activityRouter = require('./app/routes/activity')
3132
const ticketRouter = require('./app/routes/ticket')
3233

@@ -107,6 +108,7 @@ app.use('/comment', commentRouter)
107108
app.use('/project', projectRouter)
108109
app.use('/proposal', proposalRouter)
109110
app.use('/analytics', analyticsRouter)
111+
app.use('/wikis', wikisRouter)
110112
app.use('/activity', activityRouter)
111113
app.use('/ticket', ticketRouter)
112114

app/controllers/wikis.js

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
const axios = require('axios')
2+
const HttpStatus = require('http-status-codes')
3+
const WikiHelper = require('../utils/wikis-helper')
4+
const HANDLER = require('../utils/response-helper')
5+
const Organization = require('../models/Organisation')
6+
const { changeFileOnRemote, addPageToIndex, fetchPagesIndex, updatePagesIndex, getOpts, getOrgId } = WikiHelper
7+
8+
const clientId = process.env.GITHUB_OAUTH_APP_CLIENTID
9+
const clientSecret = process.env.GITHUB_OAUTH_APP_CLIENTSECRET
10+
11+
const githubAPI = 'https://api.github.com'
12+
let accessToken = null
13+
let orgId = null
14+
15+
module.exports = {
16+
17+
getWikis: async (req, res, next) => {
18+
try {
19+
if (!accessToken || !orgId) {
20+
const Org = await Organization.find({}).lean().exec()
21+
if (Org[0].wikis.accessToken && Org[0].wikis.orgId) {
22+
accessToken = Org[0].wikis.accessToken
23+
orgId = Org[0].wikis.orgId
24+
WikiHelper.setOrgId(orgId)
25+
WikiHelper.setOpts(accessToken)
26+
}
27+
}
28+
if (!accessToken || !orgId) {
29+
res.status(HttpStatus.OK).json({ wikis: 'NO_ACCESS_TOKEN' })
30+
} else {
31+
const data = await addPageToIndex(await fetchPagesIndex(), 'Home')
32+
res.status(HttpStatus.OK).json({ wikis: data })
33+
}
34+
} catch (error) {
35+
HANDLER.handleError(res, error)
36+
}
37+
},
38+
39+
getPage: async (req, res, next) => {
40+
try {
41+
let { title, ref } = req.query
42+
if (!ref) {
43+
ref = 'master'
44+
}
45+
const data = await addPageToIndex(await fetchPagesIndex(), title, ref)
46+
res.status(HttpStatus.OK).json({ wikis: data })
47+
} catch (err) {
48+
res.status(HttpStatus.BAD_REQUEST).json({ Error: err.message })
49+
}
50+
},
51+
52+
editPage: async (req, res, next) => {
53+
const { title, content, comments } = req.body
54+
try {
55+
await changeFileOnRemote(title, content, `${title} changes - ${comments}`)
56+
if (title !== '_Sidebar') {
57+
const data = await addPageToIndex(await fetchPagesIndex(), title)
58+
res.status(HttpStatus.OK).json({ wikis: data })
59+
} else {
60+
await updatePagesIndex()
61+
const data = await addPageToIndex(await fetchPagesIndex(), 'Home')
62+
res.status(HttpStatus.OK).json({ wikis: data })
63+
}
64+
} catch (err) {
65+
res.status(HttpStatus.BAD_REQUEST).json({ Error: err.message })
66+
}
67+
},
68+
69+
deletePage: async (req, res, next) => {
70+
const { title } = req.body
71+
try {
72+
const baseUrl = `${githubAPI}/repos/${getOrgId()}/Donut-wikis-backup`
73+
const data = {
74+
message: `${title} deleted`,
75+
sha: (await axios.get(`${baseUrl}/contents/${title}.md`, getOpts())).data.sha
76+
}
77+
const deleteCommit = (await axios.delete(`${baseUrl}/contents/${title}.md`, {
78+
data: data,
79+
headers: getOpts().headers
80+
})).data.commit.sha
81+
const issueNumber = await WikiHelper.getFileIssueNumber(title)
82+
await axios.post(`${baseUrl}/issues/${issueNumber}/comments`, { body: deleteCommit }, getOpts())
83+
const newIssueTitle = `${title}-deleted-${deleteCommit.substring(0, 8)}`
84+
await axios.patch(`${baseUrl}/issues/${issueNumber}`, { title: newIssueTitle }, getOpts())
85+
await updatePagesIndex()
86+
await WikiHelper.clearPageFromCache(title)
87+
res.status(HttpStatus.OK).json({ wikis: await addPageToIndex(await fetchPagesIndex(), 'Home') })
88+
} catch (err) {
89+
res.status(HttpStatus.BAD_REQUEST).json({ Error: err.message })
90+
}
91+
},
92+
93+
newPage: async (req, res, next) => {
94+
const { title, content, comments } = req.body
95+
try {
96+
await changeFileOnRemote(title, content, `${title} initial commit - ${comments}`, true)
97+
await updatePagesIndex()
98+
const data = await addPageToIndex(await fetchPagesIndex(), title)
99+
res.status(HttpStatus.OK).json({ wikis: data })
100+
} catch (err) {
101+
res.status(HttpStatus.BAD_REQUEST).json({ Error: err.message })
102+
}
103+
},
104+
105+
oauthCheck: async (req, res, next) => {
106+
if (!accessToken) {
107+
console.log('redirected to github auth')
108+
res.status(HttpStatus.OK).json({
109+
redirect: true,
110+
redirect_url: `https://github.com/login/oauth/authorize?client_id=${clientId}&scope=repo`
111+
})
112+
} else {
113+
res.status(HttpStatus.OK).json({
114+
redirect: false
115+
})
116+
}
117+
},
118+
119+
oauthCallback: async (req, res, next) => {
120+
const body = {
121+
client_id: clientId,
122+
client_secret: clientSecret,
123+
code: req.query.code
124+
}
125+
const opts = { headers: { accept: 'application/json' } }
126+
try {
127+
const resp = await axios.post('https://github.com/login/oauth/access_token', body, opts)
128+
accessToken = resp.data.access_token
129+
WikiHelper.setOpts(accessToken)
130+
const Org = await Organization.find({}).exec()
131+
orgId = await WikiHelper.getOrg()
132+
Org[0].wikis.accessToken = accessToken
133+
Org[0].wikis.orgId = orgId
134+
await Org[0].save()
135+
await WikiHelper.createRepo()
136+
await updatePagesIndex()
137+
res.redirect(`${process.env.clientbaseurl}/wikis`)
138+
} catch (err) {
139+
res.status(500).json({ message: err.message })
140+
}
141+
}
142+
}

app/models/Organisation.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ const orgSchema = new Schema({
194194
type: Date,
195195
required: true,
196196
default: Date.now()
197+
},
198+
wikis: {
199+
accessToken: { type: String, default: null },
200+
orgId: { type: String, default: null }
197201
}
198202
})
199203
module.exports = mongoose.model('Organization', orgSchema)

app/routes/wikis.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const express = require('express')
2+
const router = express.Router()
3+
const auth = require('../middleware/auth')
4+
const wikisController = require('../controllers/wikis')
5+
const isUnderMaintenance = require('../middleware/maintenance')
6+
7+
router.get(
8+
'/',
9+
isUnderMaintenance,
10+
auth,
11+
wikisController.getWikis
12+
)
13+
14+
router.get(
15+
'/oauth-callback',
16+
isUnderMaintenance,
17+
wikisController.oauthCallback
18+
)
19+
20+
router.get(
21+
'/oauth-check',
22+
isUnderMaintenance,
23+
auth,
24+
wikisController.oauthCheck
25+
)
26+
27+
router.get(
28+
'/pages',
29+
isUnderMaintenance,
30+
auth, wikisController.getPage
31+
)
32+
33+
router.post(
34+
'/pages',
35+
isUnderMaintenance,
36+
auth,
37+
wikisController.newPage
38+
)
39+
40+
router.patch(
41+
'/pages',
42+
isUnderMaintenance,
43+
auth,
44+
wikisController.editPage
45+
)
46+
47+
router.delete(
48+
'/pages',
49+
isUnderMaintenance,
50+
auth,
51+
wikisController.deletePage
52+
)
53+
54+
module.exports = router

0 commit comments

Comments
 (0)