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.
devbug/app/controllers/dash/v1.controller.js

314 lines
12 KiB

/*
* v1 Controller
* -------------------------------------------------------------
* Put some description here!
*/
const Project = _flitter.model('v1:Project')
const Out = _flitter.model('v1:Out')
const Invite = _flitter.model('v1:Invite')
class v1 {
/*
* Serve the main page.
*/
async main(req, res){
const projects = await Project.find({ archived: false, user_id: req.session.auth.uuid })
let find = {
shared_user_ids: {
$elemMatch: {
$eq: req.session.auth.uuid
}
}
}
const shared_projects = await Project.find(find)
/*
* Return the main view.
* It must be passed the response.
* View parameters can be passed as an optional third
* argument to the view() method.
*/
return _flitter.view(res, 'dash_v1:main', { projects, shared_projects, user: req.session.auth.user })
}
new_project_show(req, res, next){
return _flitter.view(res, 'dash_v1:project', { show_back: true, title: 'Create New Project' })
}
async project_edit_show(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ){
return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
}
// check access perms
if ( !(project.user_id === req.session.auth.uuid) ){
return _flitter.error(res, 401, {reason: 'You do not have permissions to edit this project.'})
}
return _flitter.view(res, 'dash_v1:project', { show_back: true, title: 'Update Project', project_name: project.name, user: req.session.auth.user })
}
async project_edit_do(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ){
return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
}
if ( !req.body || !req.body.name ){
return _flitter.view(res, 'dash_v1:project', {user: req.session.auth.user, show_back: true, title: 'Update Project', project_name: project.name, errors: ['Project name is required.']})
}
// check access perms
if ( !(project.user_id === req.session.auth.uuid) ){
return _flitter.error(res, 401, {reason: 'Project not found with the specified ID.'})
}
project.name = req.body.name
await project.save()
return res.redirect('/dash/v1')
}
async new_project_do(req, res, next){
if ( !req.body.name ){
return _flitter.view(res, 'dash_v1:project', {user: req.session.auth.user, show_back: true, title: 'Create Project', errors: ['Project name is required.']})
}
const project = new Project({
name: req.body.name,
user_id: req.session.auth.uuid,
data: JSON.stringify({
created: Date.now(),
modified: Date.now()
}),
shared_user_ids: [],
})
await project.save()
return res.redirect('/dash/v1')
}
async project_view(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ){
return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
}
const outs = await Out.find({ project_id: project.id }).sort('-created')
if ( !(project.user_id === req.session.auth.uuid) && !(project.shared_user_ids.includes(req.session.auth.uuid)) ){
return _flitter.error(res, 401, {reason: 'You do not have permission to view this project.'})
}
return _flitter.view(res, 'dash_v1:view', {user: req.session.auth.user, project, outs, show_back: true, title: 'View: '+project.name })
}
async out_view(req, res, next){
const out = await Out.findById(req.params.id)
if ( !out ){
return _flitter.error(res, 404, {reason: 'Output not found with the specified ID.'})
}
let pretty
try {
pretty = JSON.stringify(JSON.parse(out.data), null, 4)
}
catch (e){
return _flitter.error(res, 500, {reason: 'Unable to parse output data. Data contains invalid JSON.'})
}
const project = await Project.findById(out.project_id)
if ( !project || (!(project.user_id === req.session.auth.uuid) && !(project.shared_user_ids.includes(req.session.auth.uuid))) ){
return _flitter.error(res, 401, {reason: 'You do not have permission to view this project.'})
}
// TODO permission access check
return _flitter.view(res, 'dash_v1:out', {project, user: req.session.auth.user, out, prettyd:pretty, show_back: true, title: out.brief, title_small: true });
}
async out_delete(req, res, next){
const out = await Out.findById(req.params.id)
const project = await Project.findById(req.params.project)
if ( !project || ( !(project.user_id === req.session.auth.uuid) ) ){
return _flitter.error(res, 401, {reason: 'You do not have permission to edit this project.'})
}
if ( out ){
await out.delete()
}
return res.redirect('/dash/v1/project/view/'+req.params.project)
}
async project_delete_show(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ){
return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
}
if ( !(project.user_id === req.session.auth.uuid) ){
return _flitter.error(res, 401, {reason: 'You do not have permission to edit this project.'})
}
return _flitter.view(res, 'dash_v1:confirm', {user: req.session.auth.user, project, show_back: true, title: 'Are you sure?', text: 'Deleting this project will remove all stored breakpoint data. This action cannot be undone.', destination: '/dash/v1/project/delete/'+req.params.id})
}
async project_delete_do(req, res, next){
const project = await Project.findById(req.params.id)
if ( project && ( !(project.user_id === req.session.auth.uuid) ) ){
return _flitter.error(res, 401, {reason: 'You do not have permission to edit this project.'})
}
if ( project ){
const outs = await Out.find({project_id: project.id})
for ( const key in outs ){
await outs[key].delete()
}
await project.delete()
}
return res.redirect('/dash/v1')
}
view_code(req, res, next){
return _flitter.view(res, 'dash_v1:code', { user: req.session.auth.user, title: 'Using DevBug Inline' })
}
async project_share_show(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ) return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
if ( !(project.user_id === req.session.auth.uuid) ) return _flitter.error(res, 401, {reason: 'You do not have permission to edit this project.'})
let find = {
uuid: { $nin: [] }
}
find.uuid.$nin.push(req.session.auth.uuid)
find.uuid.$nin = find.uuid.$nin.concat(project.shared_user_ids)
const to_share = await _flitter.model('User').find(find)
find = {
uuid: { $in: find.uuid.$nin }
}
const shared = await _flitter.model('User').find(find)
return _flitter.view(res, 'dash_v1:share', { user: req.session.auth.user, sharing: { to_share, shared }, project, title: 'Share Project: '+project.name, show_back: true })
}
async project_share_do(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ) return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
const target_user = await _flitter.model('User').findOne({uuid: req.params.user})
if ( !target_user ) return _flitter.error(res, 404, {reason: 'User not found with the specified ID.'})
if ( !(project.user_id === req.session.auth.uuid) ) return _flitter.error(res, 401, {reason: "You do not have permission to edit this project."})
if ( !(project.user_id === target_user.uuid) && !(project.shared_user_ids.includes(target_user.uuid)) ){
project.shared_user_ids.push(target_user.uuid)
await project.save()
}
return res.redirect('/dash/v1/project/share/'+project.id)
}
async project_share_revoke(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ) return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
const target_user = await _flitter.model('User').findOne({uuid: req.params.user})
if ( !target_user ) return _flitter.error(res, 404, {reason: 'User not found with the specified ID.'})
if ( !(project.user_id === req.session.auth.uuid || project.shared_user_ids.includes(req.session.auth.uuid)) ) return _flitter.error(res, 401, {reason: "You do not have permission to edit this project."})
const to_dash = project.shared_user_ids.includes(req.session.auth.uuid)
if ( !(target_user.uuid === project.user_id) && (project.shared_user_ids.includes(target_user.uuid)) ){
project.shared_user_ids.splice(project.shared_user_ids.indexOf(target_user.uuid), 1)
await project.save()
}
if ( to_dash ) return res.redirect('/dash/v1')
return res.redirect('/dash/v1/project/share/'+project.id)
}
async project_share_transfer(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ) return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
const target_user = await _flitter.model('User').findOne({uuid: req.params.user})
if ( !target_user ) return _flitter.error(res, 404, {reason: 'User not found with the specified ID.'})
if ( !project.user_id === req.session.auth.uuid ) return _flitter.error(res, 401, {reason: 'You do not have permission to edit this project.'})
project.user_id = target_user.uuid
project.shared_user_ids.push(req.session.auth.uuid)
await project.save()
return res.redirect('/dash/v1')
}
async project_share_invite(req, res, next){
const project = await Project.findById(req.params.id)
if ( !project ) return _flitter.error(res, 404, {reason: 'Project not found with the specified ID.'})
if ( !project.user_id === req.session.auth.uuid ) return _flitter.error(res, 401, {reason: 'You do not have permission to edit this project.'})
let share_data = {
project_id: project.id,
by_user_id: req.session.auth.uuid,
created_on: Date.now()
}
const share = new Invite(share_data)
await share.save()
return _flitter.view(res, 'dash_v1:invite', {share, project, title: 'Generate Invite Link', show_back: true})
}
async accept_invite(req, res, next){
if ( !req.session.invite ) return res.redirect('/dash/v1')
const invite = await Invite.findById(req.session.invite_data.invite)
if ( !invite ) return _flitter.error(res, 404, {reason: 'This invitation is no longer valid. Sorry.'})
const project = await Project.findById(req.session.invite_data.project)
if ( !project ) return _flitter.error(res, 404, {reason: 'This project no longer exists.'})
const user = await _flitter.model('User').findById(req.session.invite_data.user)
if ( !user ) return _flitter.error(res, 404, {reason: 'This user no longer exists. Sorry.'})
if ( !project.shared_user_ids.includes(req.session.auth.uuid) && !(project.user_id === req.session.auth.uuid) ){
project.shared_user_ids.push(req.session.auth.uuid)
await project.save()
}
invite.used = true
await invite.save()
req.session.invite = false
req.session.invite_data = false
return res.redirect('/dash/v1/project/view/'+project.id)
}
}
module.exports = exports = v1