mirror of https://github.com/requarks/wiki
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
6.6 KiB
212 lines
6.6 KiB
3 years ago
|
const { Octokit, App } = require('octokit')
|
||
|
|
||
|
/* global WIKI */
|
||
|
|
||
|
module.exports = {
|
||
|
async activated () { },
|
||
|
async deactivated () { },
|
||
|
async init () { },
|
||
|
|
||
|
/**
|
||
|
* SETUP FUNCTIONS
|
||
|
*/
|
||
|
async setup (id, state) {
|
||
|
try {
|
||
|
switch (state.step) {
|
||
|
// --------------------------------------------
|
||
|
// -> VALIDATE CALLBACK CODE AFTER APP CREATION
|
||
|
// --------------------------------------------
|
||
|
case 'connect': {
|
||
|
const gh = new Octokit({
|
||
|
userAgent: 'wikijs'
|
||
|
})
|
||
|
const resp = await gh.request('POST /app-manifests/{code}/conversions', {
|
||
|
code: state.code
|
||
|
})
|
||
|
if (resp.status > 200 && resp.status < 300) {
|
||
|
await WIKI.models.storage.query().patch({
|
||
|
config: {
|
||
|
appId: resp.data.id,
|
||
|
appName: resp.data.name,
|
||
|
appSlug: resp.data.slug,
|
||
|
appClientId: resp.data.client_id,
|
||
|
appClientSecret: resp.data.client_secret,
|
||
|
appWebhookSecret: resp.data.webhook_secret,
|
||
|
appPem: resp.data.pem,
|
||
|
appPermissions: resp.data.permissions,
|
||
|
appEvents: resp.data.events,
|
||
|
ownerLogin: resp.data.owner?.login,
|
||
|
ownerId: resp.data.owner?.id
|
||
|
},
|
||
|
state: {
|
||
|
current: 'ok',
|
||
|
setup: 'pendinginstall'
|
||
|
}
|
||
|
}).where('id', id)
|
||
|
return {
|
||
|
nextStep: 'installApp',
|
||
|
url: `https://github.com/apps/${resp.data.slug}/installations/new/permissions?target_id=${resp.data.owner?.id}`
|
||
|
}
|
||
|
} else {
|
||
|
throw new Error('GitHub refused the code or could not be reached.')
|
||
|
}
|
||
|
}
|
||
|
// -----------------------
|
||
|
// VERIFY APP INSTALLATION
|
||
|
// -----------------------
|
||
|
case 'verify': {
|
||
|
const tgt = await WIKI.models.storage.query().findById(id)
|
||
|
if (!tgt) {
|
||
|
throw new Error('Invalid Target ID')
|
||
|
}
|
||
|
|
||
|
const ghApp = new App({
|
||
|
appId: tgt.config.appId,
|
||
|
privateKey: tgt.config.appPem,
|
||
|
Octokit: Octokit.defaults({
|
||
|
userAgent: 'wikijs'
|
||
|
}),
|
||
|
oauth: {
|
||
|
clientId: tgt.config.appClientId,
|
||
|
clientSecret: tgt.config.appClientSecret
|
||
|
},
|
||
|
webhooks: {
|
||
|
secret: tgt.config.appWebhookSecret
|
||
|
}
|
||
|
})
|
||
|
|
||
|
// -> Find Installation ID
|
||
|
|
||
|
let installId = null
|
||
|
let installTotal = 0
|
||
|
for await (const { installation } of ghApp.eachInstallation.iterator()) {
|
||
|
if (installTotal < 1) {
|
||
|
installId = installation.id
|
||
|
WIKI.logger.debug(`Using GitHub App installation ID ${installId}`)
|
||
|
}
|
||
|
installTotal++
|
||
|
}
|
||
|
if (installTotal < 1) {
|
||
|
throw new Error('App is not installed on any GitHub account!')
|
||
|
} else if (installTotal > 1) {
|
||
|
WIKI.logger.warn(`GitHub App ${tgt.config.appName} is installed on more than 1 account. Only the first one ${installId} will be used.`)
|
||
|
}
|
||
|
|
||
|
// -> Fetch Repository Info
|
||
|
|
||
|
let repo = null
|
||
|
let repoTotal = 0
|
||
|
for await (const { repository } of ghApp.eachRepository.iterator({ installationId: installId })) {
|
||
|
if (repository.archived || repository.disabled) {
|
||
|
WIKI.logger.debug(`Skipping GitHub Repository ${repo.id} because of it is archived or disabled.`)
|
||
|
continue
|
||
|
}
|
||
|
if (repoTotal < 1) {
|
||
|
repo = repository
|
||
|
WIKI.logger.debug(`Using GitHub Repository ${repo.id}`)
|
||
|
}
|
||
|
repoTotal++
|
||
|
}
|
||
|
if (repoTotal < 1) {
|
||
|
throw new Error('App is not installed on any GitHub repository!')
|
||
|
} else if (repoTotal > 1) {
|
||
|
WIKI.logger.warn(`GitHub App ${tgt.config.appName} is installed on more than 1 repository. Only the first one (${repo.full_name}) will be used.`)
|
||
|
}
|
||
|
|
||
|
// -> Save install/repo info
|
||
|
|
||
|
await WIKI.models.storage.query().patch({
|
||
|
isEnabled: true,
|
||
|
config: {
|
||
|
...tgt.config,
|
||
|
installId,
|
||
|
repoId: repo.id,
|
||
|
repoName: repo.name,
|
||
|
repoOwner: repo.owner?.login,
|
||
|
repoDefaultBranch: repo.default_branch,
|
||
|
repoFullName: repo.full_name
|
||
|
},
|
||
|
state: {
|
||
|
current: 'ok',
|
||
|
setup: 'configured'
|
||
|
}
|
||
|
}).where('id', id)
|
||
|
|
||
|
return {
|
||
|
nextStep: 'completed'
|
||
|
}
|
||
|
}
|
||
|
default: {
|
||
|
throw new Error('Invalid Setup Step')
|
||
|
}
|
||
|
}
|
||
|
} catch (err) {
|
||
|
WIKI.logger.warn('GitHub Storage Module Setup Failed:')
|
||
|
WIKI.logger.warn(err)
|
||
|
throw err
|
||
|
}
|
||
|
},
|
||
|
async setupDestroy (id) {
|
||
|
try {
|
||
|
const tgt = await WIKI.models.storage.query().findById(id)
|
||
|
if (!tgt) {
|
||
|
throw new Error('Invalid Target ID')
|
||
|
}
|
||
|
|
||
|
WIKI.logger.info('Resetting GitHub storage configuration...')
|
||
|
|
||
|
const ghApp = new App({
|
||
|
appId: tgt.config.appId,
|
||
|
privateKey: tgt.config.appPem,
|
||
|
Octokit: Octokit.defaults({
|
||
|
userAgent: 'wikijs'
|
||
|
}),
|
||
|
oauth: {
|
||
|
clientId: tgt.config.appClientId,
|
||
|
clientSecret: tgt.config.appClientSecret
|
||
|
},
|
||
|
webhooks: {
|
||
|
secret: tgt.config.appWebhookSecret
|
||
|
}
|
||
|
})
|
||
|
|
||
|
// -> Reset storage module config
|
||
|
|
||
|
await WIKI.models.storage.query().patch({
|
||
|
isEnabled: false,
|
||
|
config: {},
|
||
|
state: {
|
||
|
current: 'ok',
|
||
|
setup: 'notconfigured'
|
||
|
}
|
||
|
}).where('id', id)
|
||
|
|
||
|
// -> Try to delete installation on GitHub
|
||
|
|
||
|
if (tgt.config.installId) {
|
||
|
try {
|
||
|
await ghApp.octokit.request('DELETE /app/installations/{installation_id}', {
|
||
|
installation_id: tgt.config.installId
|
||
|
})
|
||
|
WIKI.logger.info('Deleted GitHub installation successfully.')
|
||
|
} catch (err) {
|
||
|
WIKI.logger.warn('Could not delete GitHub installation automatically. Please remove the installation on GitHub.')
|
||
|
}
|
||
|
}
|
||
|
} catch (err) {
|
||
|
WIKI.logger.warn('GitHub Storage Module Destroy Failed:')
|
||
|
WIKI.logger.warn(err)
|
||
|
throw err
|
||
|
}
|
||
|
},
|
||
|
async created (page) { },
|
||
|
async updated (page) { },
|
||
|
async deleted (page) { },
|
||
|
async renamed (page) { },
|
||
|
async assetUploaded (asset) { },
|
||
|
async assetDeleted (asset) { },
|
||
|
async assetRenamed (asset) { },
|
||
|
async getLocalLocation () { },
|
||
|
async exportAll () { }
|
||
|
}
|