mirror of
https://framagit.org/les/gancio.git
synced 2025-02-01 00:52:01 +01:00
parent
817359043d
commit
5f55d487db
13 changed files with 97 additions and 32 deletions
44
app/api.js
44
app/api.js
|
@ -2,44 +2,74 @@ const express = require('express')
|
||||||
const { fillUser, isAuth, isAdmin } = require('./auth')
|
const { fillUser, isAuth, isAdmin } = require('./auth')
|
||||||
const eventController = require('./controller/event')
|
const eventController = require('./controller/event')
|
||||||
const exportController = require('./controller/export')
|
const exportController = require('./controller/export')
|
||||||
|
const userController = require('./controller/user')
|
||||||
// const botController = require('./controller/bot')
|
// const botController = require('./controller/bot')
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
const multer = require('multer')
|
const multer = require('multer')
|
||||||
const upload = multer({ dest: 'uploads/' })
|
const crypto = require('crypto')
|
||||||
|
|
||||||
|
const storage = require('./storage')({
|
||||||
|
destination: 'uploads/',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
cb(null, crypto.randomBytes(16).toString('hex') + path.extname(file.originalname))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const upload = multer({ storage })
|
||||||
const api = express.Router()
|
const api = express.Router()
|
||||||
|
|
||||||
// USER API
|
// login
|
||||||
const userController = require('./controller/user')
|
|
||||||
|
|
||||||
api.post('/login', userController.login)
|
api.post('/login', userController.login)
|
||||||
|
|
||||||
api.route('/user')
|
api.route('/user')
|
||||||
|
// register
|
||||||
.post(userController.register)
|
.post(userController.register)
|
||||||
|
// get current user
|
||||||
.get(isAuth, userController.current)
|
.get(isAuth, userController.current)
|
||||||
|
// update user (eg. confirm)
|
||||||
.put(isAuth, isAdmin, userController.update)
|
.put(isAuth, isAdmin, userController.update)
|
||||||
|
|
||||||
|
// get all users
|
||||||
api.get('/users', isAuth, isAdmin, userController.getAll)
|
api.get('/users', isAuth, isAdmin, userController.getAll)
|
||||||
|
|
||||||
|
// update a tag (modify color)
|
||||||
api.put('/tag', isAuth, isAdmin, eventController.updateTag)
|
api.put('/tag', isAuth, isAdmin, eventController.updateTag)
|
||||||
|
|
||||||
|
// update a place (modify address..)
|
||||||
api.put('/place', isAuth, isAdmin, eventController.updatePlace)
|
api.put('/place', isAuth, isAdmin, eventController.updatePlace)
|
||||||
|
|
||||||
api.route('/user/event')
|
api.route('/user/event')
|
||||||
|
// add event
|
||||||
.post(fillUser, upload.single('image'), userController.addEvent)
|
.post(fillUser, upload.single('image'), userController.addEvent)
|
||||||
.get(isAuth, userController.getMyEvents)
|
// update event
|
||||||
.put(isAuth, upload.single('image'), userController.updateEvent)
|
.put(isAuth, upload.single('image'), userController.updateEvent)
|
||||||
|
|
||||||
|
// remove event
|
||||||
api.delete('/user/event/:id', isAuth, userController.delEvent)
|
api.delete('/user/event/:id', isAuth, userController.delEvent)
|
||||||
|
|
||||||
|
// get tags/places
|
||||||
api.get('/event/meta', eventController.getMeta)
|
api.get('/event/meta', eventController.getMeta)
|
||||||
api.get('/event/unconfirmed', isAuth, isAdmin, eventController.getUnconfirmed)
|
|
||||||
api.post('/event/reminder', eventController.addReminder)
|
|
||||||
|
|
||||||
|
// get unconfirmed events
|
||||||
|
api.get('/event/unconfirmed', isAuth, isAdmin, eventController.getUnconfirmed)
|
||||||
|
|
||||||
|
// add event reminder
|
||||||
|
api.post('/event/reminder', eventController.addReminder)
|
||||||
|
// api.del('/event/reminder/:id', eventController.delReminder)
|
||||||
|
|
||||||
|
// get event
|
||||||
api.get('/event/:event_id', eventController.get)
|
api.get('/event/:event_id', eventController.get)
|
||||||
|
|
||||||
|
// confirm event
|
||||||
api.get('/event/confirm/:event_id', isAuth, isAdmin, eventController.confirm)
|
api.get('/event/confirm/:event_id', isAuth, isAdmin, eventController.confirm)
|
||||||
|
|
||||||
|
// export events (rss/ics)
|
||||||
api.get('/export/:type', exportController.export)
|
api.get('/export/:type', exportController.export)
|
||||||
|
|
||||||
|
// get events in this range
|
||||||
api.get('/event/:year/:month', eventController.getAll)
|
api.get('/event/:year/:month', eventController.getAll)
|
||||||
|
|
||||||
|
// mastodon oauth auth
|
||||||
api.post('/user/getauthurl', isAuth, userController.getAuthURL)
|
api.post('/user/getauthurl', isAuth, userController.getAuthURL)
|
||||||
api.post('/user/code', isAuth, userController.code)
|
api.post('/user/code', isAuth, userController.code)
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,9 @@ const userController = {
|
||||||
async updateEvent (req, res) {
|
async updateEvent (req, res) {
|
||||||
const body = req.body
|
const body = req.body
|
||||||
const event = await Event.findByPk(body.id)
|
const event = await Event.findByPk(body.id)
|
||||||
|
if (!req.user.is_admin && event.userId !== req.user.id) {
|
||||||
|
return res.sendStatus(403)
|
||||||
|
}
|
||||||
|
|
||||||
body.description = body.description
|
body.description = body.description
|
||||||
.replace(/(<([^>]+)>)/ig, '') // remove all tags from description
|
.replace(/(<([^>]+)>)/ig, '') // remove all tags from description
|
||||||
|
@ -142,11 +145,6 @@ const userController = {
|
||||||
return res.json(newEvent)
|
return res.json(newEvent)
|
||||||
},
|
},
|
||||||
|
|
||||||
async getMyEvents (req, res) {
|
|
||||||
const events = await req.user.getEvents()
|
|
||||||
res.json(events)
|
|
||||||
},
|
|
||||||
|
|
||||||
async getAuthURL (req, res) {
|
async getAuthURL (req, res) {
|
||||||
const instance = req.body.instance
|
const instance = req.body.instance
|
||||||
const { client_id, client_secret } = await Mastodon.createOAuthApp(`https://${instance}/api/v1/apps`, 'eventi', 'read write', `${config.baseurl}/settings`)
|
const { client_id, client_secret } = await Mastodon.createOAuthApp(`https://${instance}/api/v1/apps`, 'eventi', 'read write', `${config.baseurl}/settings`)
|
||||||
|
|
|
@ -3,7 +3,7 @@ const conf = require('./config.js')
|
||||||
console.error(conf.db)
|
console.error(conf.db)
|
||||||
const db = new Sequelize(conf.db)
|
const db = new Sequelize(conf.db)
|
||||||
|
|
||||||
//db.sync({ force: true })
|
// db.sync({ force: true })
|
||||||
// db.sync()
|
// db.sync()
|
||||||
|
|
||||||
module.exports = db
|
module.exports = db
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/app'
|
'@vue/app' //, 'es2015', { 'modules': false }
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
[
|
||||||
|
'component',
|
||||||
|
{
|
||||||
|
'libraryName': 'element-ui',
|
||||||
|
'styleLibraryName': 'theme-chalk'
|
||||||
|
}
|
||||||
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
|
"babel-plugin-component": "^1.1.1",
|
||||||
"bootstrap-vue": "^2.0.0-rc.13",
|
"bootstrap-vue": "^2.0.0-rc.13",
|
||||||
|
"dayjs": "^1.8.9",
|
||||||
"element-ui": "^2.6.1",
|
"element-ui": "^2.6.1",
|
||||||
"mastodon-api": "^1.3.0",
|
"mastodon-api": "^1.3.0",
|
||||||
"moment": "^2.23.0",
|
|
||||||
"node-sass": "^4.11.0",
|
"node-sass": "^4.11.0",
|
||||||
"npm": "^6.8.0",
|
"npm": "^6.8.0",
|
||||||
"postcss-flexbugs-fixes": "^4.1.0",
|
"postcss-flexbugs-fixes": "^4.1.0",
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import moment from 'moment'
|
import moment from 'dayjs'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
import Register from '@/components/Register'
|
import Register from '@/components/Register'
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapActions } from 'vuex'
|
import { mapState, mapActions } from 'vuex'
|
||||||
import filters from '@/filters'
|
import filters from '@/filters'
|
||||||
import moment from 'moment'
|
import moment from 'dayjs'
|
||||||
import { intersection } from 'lodash'
|
import { intersection } from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import filters from '@/filters.js'
|
||||||
import Event from '@/components/Event'
|
import Event from '@/components/Event'
|
||||||
import Calendar from '@/components/Calendar'
|
import Calendar from '@/components/Calendar'
|
||||||
import {intersection} from 'lodash'
|
import {intersection} from 'lodash'
|
||||||
import moment from 'moment'
|
import moment from 'dayjs'
|
||||||
import Search from '@/components/Search'
|
import Search from '@/components/Search'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<script>
|
<script>
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { mapActions, mapState } from 'vuex'
|
import { mapActions, mapState } from 'vuex'
|
||||||
import moment from 'moment'
|
import moment from 'dayjs'
|
||||||
import Calendar from './Calendar'
|
import Calendar from './Calendar'
|
||||||
export default {
|
export default {
|
||||||
components: { Calendar },
|
components: { Calendar },
|
||||||
|
@ -158,10 +158,9 @@ export default {
|
||||||
end_datetime = moment(this.date.end)
|
end_datetime = moment(this.date.end)
|
||||||
.hour(end_hour).minute(end_minute)
|
.hour(end_hour).minute(end_minute)
|
||||||
} else {
|
} else {
|
||||||
start_datetime = moment(this.date)
|
console.log(this.date)
|
||||||
.hour(start_hour).minute(start_minute)
|
start_datetime = moment(this.date).set('hour', start_hour).set('minute', start_minute)
|
||||||
end_datetime = moment(this.date)
|
end_datetime = moment(this.date).set('hour', end_hour).set('minute', end_minute)
|
||||||
.hour(end_hour).minute(end_minute)
|
|
||||||
}
|
}
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import moment from 'moment'
|
import moment from 'dayjs'
|
||||||
moment.locale('it')
|
// moment.locale('it')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
datetime (value) {
|
datetime (value) {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import VueI18n from 'vue-i18n'
|
||||||
import BootstrapVue from 'bootstrap-vue'
|
import BootstrapVue from 'bootstrap-vue'
|
||||||
import VCalendar from 'v-calendar'
|
import VCalendar from 'v-calendar'
|
||||||
|
|
||||||
// import 'vue-awesome/icons'
|
|
||||||
import 'vue-awesome/icons/lock'
|
import 'vue-awesome/icons/lock'
|
||||||
import 'vue-awesome/icons/plus'
|
import 'vue-awesome/icons/plus'
|
||||||
import 'vue-awesome/icons/cog'
|
import 'vue-awesome/icons/cog'
|
||||||
|
@ -25,9 +24,14 @@ import VueClipboard from 'vue-clipboard2'
|
||||||
|
|
||||||
import 'v-calendar/lib/v-calendar.min.css'
|
import 'v-calendar/lib/v-calendar.min.css'
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
import 'bootstrap/dist/css/bootstrap.css'
|
||||||
// import 'bootstrap-vue/dist/bootstrap-vue.css'
|
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||||
|
|
||||||
|
import { Button, Select, Tag, Option, Table, FormItem,
|
||||||
|
Form, Tabs, TabPane, Switch, Input, Loading, TimeSelect,
|
||||||
|
TableColumn, ColorPicker, Pagination } from 'element-ui'
|
||||||
|
import ElementLocale from 'element-ui/lib/locale'
|
||||||
|
|
||||||
|
|
||||||
import ElementUI from 'element-ui'
|
|
||||||
import 'element-ui/lib/theme-chalk/index.css'
|
import 'element-ui/lib/theme-chalk/index.css'
|
||||||
|
|
||||||
import itElementLocale from 'element-ui/lib/locale/lang/it'
|
import itElementLocale from 'element-ui/lib/locale/lang/it'
|
||||||
|
@ -42,6 +46,23 @@ import './assets/main.css'
|
||||||
import itLocale from '@/locale/it'
|
import itLocale from '@/locale/it'
|
||||||
import enLocale from '@/locale/en'
|
import enLocale from '@/locale/en'
|
||||||
|
|
||||||
|
Vue.use(Button)
|
||||||
|
Vue.use(Select)
|
||||||
|
Vue.use(Tag)
|
||||||
|
Vue.use(Input)
|
||||||
|
Vue.use(Tabs)
|
||||||
|
Vue.use(TabPane)
|
||||||
|
Vue.use(Option)
|
||||||
|
Vue.use(Switch)
|
||||||
|
Vue.use(ColorPicker)
|
||||||
|
Vue.use(Table)
|
||||||
|
Vue.use(TableColumn)
|
||||||
|
Vue.use(Pagination)
|
||||||
|
Vue.use(FormItem)
|
||||||
|
Vue.use(Form)
|
||||||
|
Vue.use(TimeSelect)
|
||||||
|
Vue.use(Loading.directive)
|
||||||
|
|
||||||
// Use v-calendar, v-date-picker & v-popover components
|
// Use v-calendar, v-date-picker & v-popover components
|
||||||
Vue.use(VCalendar, {
|
Vue.use(VCalendar, {
|
||||||
firstDayOfWeek: 2
|
firstDayOfWeek: 2
|
||||||
|
@ -50,7 +71,6 @@ Vue.use(BootstrapVue)
|
||||||
Vue.use(VueI18n)
|
Vue.use(VueI18n)
|
||||||
Vue.use(VueClipboard)
|
Vue.use(VueClipboard)
|
||||||
Vue.component('v-icon', Icon)
|
Vue.component('v-icon', Icon)
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
en: {
|
en: {
|
||||||
...enElementLocale,
|
...enElementLocale,
|
||||||
|
@ -68,13 +88,14 @@ const i18n = new VueI18n({
|
||||||
messages // set locale messages
|
messages // set locale messages
|
||||||
})
|
})
|
||||||
|
|
||||||
Vue.use(ElementUI, { i18n: (key, value) => i18n.t(key, value) })
|
// Vue.use(ElementUI, { i18n: (key, value) => i18n.t(key, value) })
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
Vue.config.lang = 'it'
|
Vue.config.lang = 'it'
|
||||||
|
// Vue.locale('en', enLocale)
|
||||||
Vue.config.devtools = true
|
Vue.config.devtools = true
|
||||||
Vue.config.silent = false
|
Vue.config.silent = false
|
||||||
|
ElementLocale.i18n((key, value) => i18n.t(key, value))
|
||||||
new Vue({
|
new Vue({
|
||||||
i18n,
|
i18n,
|
||||||
router,
|
router,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Vuex from 'vuex'
|
||||||
import VuexPersistence from 'vuex-persist'
|
import VuexPersistence from 'vuex-persist'
|
||||||
import { intersection } from 'lodash'
|
import { intersection } from 'lodash'
|
||||||
import api from './api'
|
import api from './api'
|
||||||
import moment from 'moment'
|
import moment from 'dayjs'
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
const vuexLocal = new VuexPersistence({
|
const vuexLocal = new VuexPersistence({
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
process.env.VUE_APP_API = process.env.NODE_ENV === 'production' ? process.env.BASE_URL || 'http://localhost:9000' : 'http://localhost:9000'
|
process.env.VUE_APP_API = process.env.NODE_ENV === 'production' ? process.env.BASE_URL || 'http://localhost:9000' : 'http://localhost:9000'
|
||||||
process.env.VUE_APP_TITLE = process.env.TITLE || 'Gancio'
|
process.env.VUE_APP_TITLE = process.env.TITLE || 'Gancio'
|
||||||
process.env.VUE_APP_DESCRIPTION = process.env.DESCRIPTION || 'Event manager for radical movements'
|
process.env.VUE_APP_DESCRIPTION = process.env.DESCRIPTION || 'Event manager for radical movements'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
publicPath: process.env.BASE_URL,
|
publicPath: process.env.BASE_URL,
|
||||||
|
configureWebpack: {
|
||||||
|
plugins: [
|
||||||
|
new webpack.NormalModuleReplacementPlugin(/element-ui[\/\\]lib[\/\\]locale[\/\\]lang[\/\\]zh-CN/, 'element-ui/lib/locale/lang/en')
|
||||||
|
]
|
||||||
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
disableHostCheck: true
|
disableHostCheck: true
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue