linting
This commit is contained in:
@@ -22,7 +22,7 @@ export default {
|
|||||||
const month = moment().month() + 1
|
const month = moment().month() + 1
|
||||||
const year = moment().year()
|
const year = moment().year()
|
||||||
return {
|
return {
|
||||||
page: { month, year},
|
page: { month, year }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -35,8 +35,8 @@ export default {
|
|||||||
...mapActions(['updateEvents']),
|
...mapActions(['updateEvents']),
|
||||||
click (day) {
|
click (day) {
|
||||||
const element = document.getElementById(day.day)
|
const element = document.getElementById(day.day)
|
||||||
if (element) element.scrollIntoView(); //Even IE6 supports this
|
if (element) { element.scrollIntoView() } // Even IE6 supports this
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['filteredEventsWithPast']),
|
...mapGetters(['filteredEventsWithPast']),
|
||||||
@@ -53,9 +53,9 @@ export default {
|
|||||||
function getColor (event) {
|
function getColor (event) {
|
||||||
const color = { class: event.past && !that.filters.show_past_events ? 'past-event vc-rounded-full' : 'vc-rounded-full', color: 'blue' }
|
const color = { class: event.past && !that.filters.show_past_events ? 'past-event vc-rounded-full' : 'vc-rounded-full', color: 'blue' }
|
||||||
const tag = get(event, 'tags[0]')
|
const tag = get(event, 'tags[0]')
|
||||||
if (!tag) return color
|
if (!tag) { return color }
|
||||||
const idx = tags.indexOf(tag)
|
const idx = tags.indexOf(tag)
|
||||||
if (idx<0) return color
|
if (idx < 0) { return color }
|
||||||
color.color = colors[idx]
|
color.color = colors[idx]
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
@@ -68,11 +68,14 @@ export default {
|
|||||||
key: e.id,
|
key: e.id,
|
||||||
dot: color,
|
dot: color,
|
||||||
dates: new Date(e.start_datetime * 1000)
|
dates: new Date(e.start_datetime * 1000)
|
||||||
}}))
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
attributes = attributes.concat(this.filteredEventsWithPast
|
attributes = attributes.concat(this.filteredEventsWithPast
|
||||||
.filter(e => e.multidate)
|
.filter(e => e.multidate)
|
||||||
.map( e => ({ key: e.id, highlight: getColor(e), dates: {
|
.map(e => ({ key: e.id,
|
||||||
|
highlight: getColor(e),
|
||||||
|
dates: {
|
||||||
start: new Date(e.start_datetime * 1000), end: new Date(e.end_datetime * 1000) } })))
|
start: new Date(e.start_datetime * 1000), end: new Date(e.end_datetime * 1000) } })))
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default {
|
|||||||
showImage: {
|
showImage: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
date () {
|
date () {
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ export default {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: { Calendar, Event },
|
||||||
data () {
|
data () {
|
||||||
return { }
|
return { }
|
||||||
},
|
},
|
||||||
components: { Calendar, Event },
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['filteredEvents']),
|
...mapGetters(['filteredEvents']),
|
||||||
...mapState(['events', 'settings'])
|
...mapState(['events', 'settings'])
|
||||||
|
|||||||
@@ -20,17 +20,6 @@ import { mapGetters } from 'vuex'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'List',
|
name: 'List',
|
||||||
data () {
|
|
||||||
return { }
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
link (event) {
|
|
||||||
if (event.recurrent) {
|
|
||||||
return `${event.id}_${event.start_datetime}`
|
|
||||||
}
|
|
||||||
return event.id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -52,17 +41,28 @@ export default {
|
|||||||
},
|
},
|
||||||
showTags: {
|
showTags: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
showImage: {
|
showImage: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
showDescription: {
|
showDescription: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
data () {
|
||||||
|
return { }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
link (event) {
|
||||||
|
if (event.recurrent) {
|
||||||
|
return `${event.id}_${event.start_datetime}`
|
||||||
|
}
|
||||||
|
return event.id
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang='less'>
|
<style lang='less'>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default {
|
|||||||
could_add () {
|
could_add () {
|
||||||
return (this.$auth.loggedIn || this.settings.allow_anon_event)
|
return (this.$auth.loggedIn || this.settings.allow_anon_event)
|
||||||
},
|
},
|
||||||
...mapState(['filters', 'settings']),
|
...mapState(['filters', 'settings'])
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
logout () {
|
logout () {
|
||||||
|
|||||||
@@ -33,16 +33,16 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapState, mapActions } from 'vuex'
|
import { mapState, mapActions } from 'vuex'
|
||||||
export default {
|
export default {
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
onlyMine: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: 'Search',
|
name: 'Search',
|
||||||
props: {
|
props: {
|
||||||
pastFilter: Boolean,
|
pastFilter: Boolean,
|
||||||
recurrentFilter: Boolean
|
recurrentFilter: Boolean
|
||||||
},
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
onlyMine: false
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents', 'showRecurrentEvents']),
|
methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents', 'showRecurrentEvents']),
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['tags', 'places', 'filters', 'settings']),
|
...mapState(['tags', 'places', 'filters', 'settings']),
|
||||||
@@ -70,7 +70,7 @@ export default {
|
|||||||
get () {
|
get () {
|
||||||
return this.filters.tags.map(t => 't' + t).concat(this.filters.places.map(p => 'p' + p))
|
return this.filters.tags.map(t => 't' + t).concat(this.filters.places.map(p => 'p' + p))
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default {
|
|||||||
paginatedPlaces () {
|
paginatedPlaces () {
|
||||||
return this.places.slice((this.placePage - 1) * this.perPage,
|
return this.places.slice((this.placePage - 1) * this.perPage,
|
||||||
this.placePage * this.perPage)
|
this.placePage * this.perPage)
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
placeSelected (items) {
|
placeSelected (items) {
|
||||||
@@ -51,8 +51,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async savePlace () {
|
async savePlace () {
|
||||||
const place = await this.$axios.$put('/place', this.place)
|
const place = await this.$axios.$put('/place', this.place)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export default {
|
|||||||
userPage: 1,
|
userPage: 1,
|
||||||
new_user: {
|
new_user: {
|
||||||
email: '',
|
email: '',
|
||||||
is_admin: false,
|
is_admin: false
|
||||||
},
|
},
|
||||||
users_: this.users
|
users_: this.users
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ export default {
|
|||||||
paginatedUsers () {
|
paginatedUsers () {
|
||||||
return this.users_.slice((this.userPage - 1) * this.perPage,
|
return this.users_.slice((this.userPage - 1) * this.perPage,
|
||||||
this.userPage * this.perPage)
|
this.userPage * this.perPage)
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async delete_user (user) {
|
async delete_user (user) {
|
||||||
@@ -114,7 +114,7 @@ export default {
|
|||||||
message: this.$t(e)
|
message: this.$t(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,176 +1,175 @@
|
|||||||
// Event handling
|
// Event handling
|
||||||
|
|
||||||
function addEvent (el, type, handler) {
|
function addEvent (el, type, handler) {
|
||||||
if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
|
if (el.attachEvent) { el.attachEvent('on' + type, handler) } else { el.addEventListener(type, handler) }
|
||||||
}
|
}
|
||||||
function removeEvent (el, type, handler) {
|
function removeEvent (el, type, handler) {
|
||||||
if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler);
|
if (el.detachEvent) { el.detachEvent('on' + type, handler) } else { el.removeEventListener(type, handler) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show/hide mobile menu
|
// Show/hide mobile menu
|
||||||
|
|
||||||
function toggleNav () {
|
function toggleNav () {
|
||||||
const nav = document.querySelector('.js-main-nav');
|
const nav = document.querySelector('.js-main-nav')
|
||||||
const auxNav = document.querySelector('.js-aux-nav');
|
const auxNav = document.querySelector('.js-aux-nav')
|
||||||
const navTrigger = document.querySelector('.js-main-nav-trigger');
|
const navTrigger = document.querySelector('.js-main-nav-trigger')
|
||||||
const search = document.querySelector('.js-search');
|
const search = document.querySelector('.js-search')
|
||||||
|
|
||||||
addEvent(navTrigger, 'click', function () {
|
addEvent(navTrigger, 'click', function () {
|
||||||
var text = navTrigger.innerText;
|
const text = navTrigger.textContent
|
||||||
var textToggle = navTrigger.getAttribute('data-text-toggle');
|
let textToggle = navTrigger.getAttribute('data-text-toggle')
|
||||||
|
|
||||||
nav.classList.toggle('nav-open');
|
nav.classList.toggle('nav-open')
|
||||||
auxNav.classList.toggle('nav-open');
|
auxNav.classList.toggle('nav-open')
|
||||||
navTrigger.classList.toggle('nav-open');
|
navTrigger.classList.toggle('nav-open')
|
||||||
search.classList.toggle('nav-open');
|
search.classList.toggle('nav-open')
|
||||||
navTrigger.innerText = textToggle;
|
navTrigger.textContent = textToggle
|
||||||
navTrigger.setAttribute('data-text-toggle', text);
|
navTrigger.setAttribute('data-text-toggle', text)
|
||||||
textToggle = text;
|
textToggle = text
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Site search
|
// Site search
|
||||||
|
|
||||||
function initSearch () {
|
function initSearch () {
|
||||||
var index = lunr(function () {
|
const index = lunr(function () {
|
||||||
this.ref('id');
|
this.ref('id')
|
||||||
this.field('title', { boost: 20 });
|
this.field('title', { boost: 20 })
|
||||||
this.field('content', { boost: 10 });
|
this.field('content', { boost: 10 })
|
||||||
this.field('url');
|
this.field('url')
|
||||||
});
|
})
|
||||||
|
|
||||||
// Get the generated search_data.json file so lunr.js can search it locally.
|
// Get the generated search_data.json file so lunr.js can search it locally.
|
||||||
|
|
||||||
sc = document.getElementsByTagName("script");
|
sc = document.getElementsByTagName('script')
|
||||||
source = '';
|
source = ''
|
||||||
|
|
||||||
for(idx = 0; idx < sc.length; idx++)
|
for (idx = 0; idx < sc.length; idx++) {
|
||||||
{
|
s = sc.item(idx)
|
||||||
s = sc.item(idx);
|
|
||||||
|
|
||||||
if(s.src && s.src.match(/just-the-docs\.js$/))
|
if (s.src && s.src.match(/just-the-docs\.js$/)) { source = s.src }
|
||||||
{ source = s.src; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsPath = source.replace('just-the-docs.js', '');
|
jsPath = source.replace('just-the-docs.js', '')
|
||||||
|
|
||||||
jsonPath = jsPath + 'search-data.json';
|
jsonPath = jsPath + 'search-data.json'
|
||||||
|
|
||||||
var request = new XMLHttpRequest();
|
const request = new XMLHttpRequest()
|
||||||
request.open('GET', jsonPath, true);
|
request.open('GET', jsonPath, true)
|
||||||
|
|
||||||
request.onload = function () {
|
request.onload = function () {
|
||||||
if (request.status >= 200 && request.status < 400) {
|
if (request.status >= 200 && request.status < 400) {
|
||||||
// Success!
|
// Success!
|
||||||
var data = JSON.parse(request.responseText);
|
const data = JSON.parse(request.responseText)
|
||||||
var keys = Object.keys(data);
|
const keys = Object.keys(data)
|
||||||
|
|
||||||
for(var i in data) {
|
for (const i in data) {
|
||||||
index.add({
|
index.add({
|
||||||
id: data[i].id,
|
id: data[i].id,
|
||||||
title: data[i].title,
|
title: data[i].title,
|
||||||
content: data[i].content,
|
content: data[i].content,
|
||||||
url: data[i].url
|
url: data[i].url
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
searchResults(data);
|
searchResults(data)
|
||||||
} else {
|
} else {
|
||||||
// We reached our target server, but it returned an error
|
// We reached our target server, but it returned an error
|
||||||
console.log('Error loading ajax request. Request status:' + request.status);
|
console.log('Error loading ajax request. Request status:' + request.status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
request.onerror = function () {
|
request.onerror = function () {
|
||||||
// There was a connection error of some sort
|
// There was a connection error of some sort
|
||||||
console.log('There was a connection error');
|
console.log('There was a connection error')
|
||||||
};
|
}
|
||||||
|
|
||||||
request.send();
|
request.send()
|
||||||
|
|
||||||
function searchResults (dataStore) {
|
function searchResults (dataStore) {
|
||||||
var searchInput = document.querySelector('.js-search-input');
|
const searchInput = document.querySelector('.js-search-input')
|
||||||
var searchResults = document.querySelector('.js-search-results');
|
const searchResults = document.querySelector('.js-search-results')
|
||||||
var store = dataStore;
|
const store = dataStore
|
||||||
|
|
||||||
function hideResults () {
|
function hideResults () {
|
||||||
searchResults.innerHTML = '';
|
searchResults.innerHTML = ''
|
||||||
searchResults.classList.remove('active');
|
searchResults.classList.remove('active')
|
||||||
}
|
}
|
||||||
|
|
||||||
addEvent(searchInput, 'keyup', function (e) {
|
addEvent(searchInput, 'keyup', function (e) {
|
||||||
var query = this.value;
|
const query = this.value
|
||||||
|
|
||||||
searchResults.innerHTML = '';
|
searchResults.innerHTML = ''
|
||||||
searchResults.classList.remove('active');
|
searchResults.classList.remove('active')
|
||||||
|
|
||||||
if (query === '') {
|
if (query === '') {
|
||||||
hideResults();
|
hideResults()
|
||||||
} else {
|
} else {
|
||||||
var results = index.search(query);
|
const results = index.search(query)
|
||||||
|
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
searchResults.classList.add('active');
|
searchResults.classList.add('active')
|
||||||
var resultsList = document.createElement('ul');
|
const resultsList = document.createElement('ul')
|
||||||
searchResults.appendChild(resultsList);
|
searchResults.appendChild(resultsList)
|
||||||
|
|
||||||
for (var i in results) {
|
for (const i in results) {
|
||||||
var resultsListItem = document.createElement('li');
|
const resultsListItem = document.createElement('li')
|
||||||
var resultsLink = document.createElement('a');
|
const resultsLink = document.createElement('a')
|
||||||
var resultsUrlDesc = document.createElement('span');
|
const resultsUrlDesc = document.createElement('span')
|
||||||
var resultsUrl = store[results[i].ref].url;
|
const resultsUrl = store[results[i].ref].url
|
||||||
var resultsRelUrl = store[results[i].ref].relUrl;
|
const resultsRelUrl = store[results[i].ref].relUrl
|
||||||
var resultsTitle = store[results[i].ref].title;
|
const resultsTitle = store[results[i].ref].title
|
||||||
|
|
||||||
resultsLink.setAttribute('href', resultsUrl);
|
resultsLink.setAttribute('href', resultsUrl)
|
||||||
resultsLink.innerText = resultsTitle;
|
resultsLink.textContent = resultsTitle
|
||||||
resultsUrlDesc.innerText = resultsRelUrl;
|
resultsUrlDesc.textContent = resultsRelUrl
|
||||||
|
|
||||||
resultsList.classList.add('search-results-list');
|
resultsList.classList.add('search-results-list')
|
||||||
resultsListItem.classList.add('search-results-list-item');
|
resultsListItem.classList.add('search-results-list-item')
|
||||||
resultsLink.classList.add('search-results-link');
|
resultsLink.classList.add('search-results-link')
|
||||||
resultsUrlDesc.classList.add('fs-2','text-grey-dk-000','d-block');
|
resultsUrlDesc.classList.add('fs-2', 'text-grey-dk-000', 'd-block')
|
||||||
|
|
||||||
resultsList.appendChild(resultsListItem);
|
resultsList.appendChild(resultsListItem)
|
||||||
resultsListItem.appendChild(resultsLink);
|
resultsListItem.appendChild(resultsLink)
|
||||||
resultsLink.appendChild(resultsUrlDesc);
|
resultsLink.appendChild(resultsUrlDesc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When esc key is pressed, hide the results and clear the field
|
// When esc key is pressed, hide the results and clear the field
|
||||||
if (e.keyCode == 27) {
|
if (e.keyCode == 27) {
|
||||||
hideResults();
|
hideResults()
|
||||||
searchInput.value = '';
|
searchInput.value = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
addEvent(searchInput, 'blur', function () {
|
addEvent(searchInput, 'blur', function () {
|
||||||
setTimeout(function(){ hideResults() }, 300);
|
setTimeout(function () { hideResults() }, 300)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pageFocus () {
|
function pageFocus () {
|
||||||
var mainContent = document.querySelector('.js-main-content');
|
const mainContent = document.querySelector('.js-main-content')
|
||||||
mainContent.focus();
|
mainContent.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Document ready
|
// Document ready
|
||||||
|
|
||||||
function ready () {
|
function ready () {
|
||||||
toggleNav();
|
toggleNav()
|
||||||
pageFocus();
|
pageFocus()
|
||||||
if (typeof lunr !== 'undefined') {
|
if (typeof lunr !== 'undefined') {
|
||||||
initSearch();
|
initSearch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case the document is already rendered
|
// in case the document is already rendered
|
||||||
if (document.readyState!='loading') ready();
|
if (document.readyState != 'loading') { ready() }
|
||||||
// modern browsers
|
// modern browsers
|
||||||
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', ready);
|
else if (document.addEventListener) { document.addEventListener('DOMContentLoaded', ready) }
|
||||||
// IE <= 8
|
// IE <= 8
|
||||||
else document.attachEvent('onreadystatechange', function(){
|
else {
|
||||||
if (document.readyState=='complete') ready();
|
document.attachEvent('onreadystatechange', function () {
|
||||||
});
|
if (document.readyState == 'complete') { ready() }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ['error'],
|
props: ['error']
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ Adding this link to your feed reader will keep you up to date.`,
|
|||||||
password_updated: 'Password updated',
|
password_updated: 'Password updated',
|
||||||
danger_section: 'Dangerous section',
|
danger_section: 'Dangerous section',
|
||||||
remove_account: 'By pressing the following button your user will be deleted. The events you published instead no.',
|
remove_account: 'By pressing the following button your user will be deleted. The events you published instead no.',
|
||||||
remove_account_confirm: 'You are about to permanently delete your account',
|
remove_account_confirm: 'You are about to permanently delete your account'
|
||||||
},
|
},
|
||||||
|
|
||||||
error: {
|
error: {
|
||||||
@@ -171,7 +171,7 @@ Adding this link to your feed reader will keep you up to date.`,
|
|||||||
3: 'third',
|
3: 'third',
|
||||||
4: 'fourth',
|
4: 'fourth',
|
||||||
5: 'fifth',
|
5: 'fifth',
|
||||||
[-1]: 'last',
|
[-1]: 'last'
|
||||||
},
|
},
|
||||||
|
|
||||||
about: `
|
about: `
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export default {
|
|||||||
password_updated: 'Contraseña modificada',
|
password_updated: 'Contraseña modificada',
|
||||||
danger_section: 'Sección peligrosa',
|
danger_section: 'Sección peligrosa',
|
||||||
remove_account: 'Al presionar el siguiente botón, su usuario será eliminado. No serán eliminados los eventos que publicaste.',
|
remove_account: 'Al presionar el siguiente botón, su usuario será eliminado. No serán eliminados los eventos que publicaste.',
|
||||||
remove_account_confirm: 'Estás por borrar definitivamente tu cuenta',
|
remove_account_confirm: 'Estás por borrar definitivamente tu cuenta'
|
||||||
},
|
},
|
||||||
|
|
||||||
error: {
|
error: {
|
||||||
@@ -176,7 +176,7 @@ export default {
|
|||||||
3: 'tercero',
|
3: 'tercero',
|
||||||
4: 'cuarto',
|
4: 'cuarto',
|
||||||
5: 'quinto',
|
5: 'quinto',
|
||||||
[-1]: 'último',
|
[-1]: 'último'
|
||||||
},
|
},
|
||||||
|
|
||||||
about: `
|
about: `
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export default {
|
|||||||
password_updated: 'Password modificata',
|
password_updated: 'Password modificata',
|
||||||
danger_section: 'Sezione pericolosa',
|
danger_section: 'Sezione pericolosa',
|
||||||
remove_account: 'Premendo il seguente tasto il tuo utente verrà eliminato. Gli eventi da te pubblicati invece no.',
|
remove_account: 'Premendo il seguente tasto il tuo utente verrà eliminato. Gli eventi da te pubblicati invece no.',
|
||||||
remove_account_confirm: 'Stai per eliminare definitivamente il tuo account',
|
remove_account_confirm: 'Stai per eliminare definitivamente il tuo account'
|
||||||
},
|
},
|
||||||
|
|
||||||
error: {
|
error: {
|
||||||
@@ -175,7 +175,7 @@ export default {
|
|||||||
confirm: {
|
confirm: {
|
||||||
title: 'Conferma utente',
|
title: 'Conferma utente',
|
||||||
not_valid: 'Mmmmm qualcosa è andato storto.',
|
not_valid: 'Mmmmm qualcosa è andato storto.',
|
||||||
valid: 'Il tuo account è stato confermato, ora puoi <a href="/login">entrare</a>',
|
valid: 'Il tuo account è stato confermato, ora puoi <a href="/login">entrare</a>'
|
||||||
},
|
},
|
||||||
|
|
||||||
ordinal: {
|
ordinal: {
|
||||||
@@ -184,7 +184,7 @@ export default {
|
|||||||
3: 'terzo',
|
3: 'terzo',
|
||||||
4: 'quarto',
|
4: 'quarto',
|
||||||
5: 'quinto',
|
5: 'quinto',
|
||||||
[-1]: 'ultimo',
|
[-1]: 'ultimo'
|
||||||
},
|
},
|
||||||
|
|
||||||
about: `
|
about: `
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ module.exports = {
|
|||||||
head: {
|
head: {
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: 'utf-8' },
|
{ charset: 'utf-8' },
|
||||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||||
],
|
],
|
||||||
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
|
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
|
||||||
},
|
},
|
||||||
@@ -29,7 +29,6 @@ module.exports = {
|
|||||||
'element-ui/lib/theme-chalk/index.css'
|
'element-ui/lib/theme-chalk/index.css'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Plugins to load before mounting the App
|
** Plugins to load before mounting the App
|
||||||
*/
|
*/
|
||||||
@@ -49,7 +48,7 @@ module.exports = {
|
|||||||
['nuxt-express-module', { expressPath: 'server/', routesPath: 'server/routes' }],
|
['nuxt-express-module', { expressPath: 'server/', routesPath: 'server/routes' }],
|
||||||
// Doc: https://axios.nuxtjs.org/usage
|
// Doc: https://axios.nuxtjs.org/usage
|
||||||
'@nuxtjs/axios',
|
'@nuxtjs/axios',
|
||||||
'@nuxtjs/auth',
|
'@nuxtjs/auth'
|
||||||
],
|
],
|
||||||
/*
|
/*
|
||||||
** Axios module configuration
|
** Axios module configuration
|
||||||
@@ -94,6 +93,6 @@ module.exports = {
|
|||||||
splitChunks: {
|
splitChunks: {
|
||||||
layouts: true
|
layouts: true
|
||||||
},
|
},
|
||||||
cache: true,
|
cache: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"author": "lesion",
|
"author": "lesion",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:nuxt": "cross-env NODE_ENV=development nuxt dev",
|
"dev:nuxt": "cross-env NODE_ENV=development nuxt dev",
|
||||||
"dev": "cross-env DEBUG=*,-follow-redirects,-send,-body-parser:*,-express:*,-connect:*,-sequelize:* NODE_ENV=development node server/index.js",
|
"dev": "cross-env DEBUG=*,-babel,-follow-redirects,-send,-body-parser:*,-express:*,-connect:*,-sequelize:* NODE_ENV=development node server/index.js",
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
"start": "cross-env NODE_ENV=production node server/cli.js",
|
"start": "cross-env NODE_ENV=production node server/cli.js",
|
||||||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
|
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
el-button.float-right(@click.native='next' :disabled='!couldProceed') {{$t('common.next')}}
|
el-button.float-right(@click.native='next' :disabled='!couldProceed') {{$t('common.next')}}
|
||||||
|
|
||||||
|
|
||||||
//- WHERE
|
//- WHERE
|
||||||
el-tab-pane
|
el-tab-pane
|
||||||
span(slot='label') <v-icon name='map-marker-alt'/> {{$t('common.where')}}
|
span(slot='label') <v-icon name='map-marker-alt'/> {{$t('common.where')}}
|
||||||
@@ -123,6 +122,7 @@ import { Message } from 'element-ui'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Add',
|
name: 'Add',
|
||||||
|
name: 'newEvent',
|
||||||
components: { List },
|
components: { List },
|
||||||
validate ({ store }) {
|
validate ({ store }) {
|
||||||
return (store.state.auth.loggedIn || store.state.settings.allow_anon_event)
|
return (store.state.auth.loggedIn || store.state.settings.allow_anon_event)
|
||||||
@@ -139,25 +139,26 @@ export default {
|
|||||||
event: {
|
event: {
|
||||||
type: 'normal',
|
type: 'normal',
|
||||||
place: { name: '', address: '' },
|
place: { name: '', address: '' },
|
||||||
title: '', description: '', tags: [],
|
title: '',
|
||||||
|
description: '',
|
||||||
|
tags: [],
|
||||||
image: false,
|
image: false,
|
||||||
recurrent: { frequency: '1w', days: [], type: 'weekday' },
|
recurrent: { frequency: '1w', days: [], type: 'weekday' }
|
||||||
},
|
},
|
||||||
page: { month, year },
|
page: { month, year },
|
||||||
fileList: [],
|
fileList: [],
|
||||||
id: null,
|
id: null,
|
||||||
activeTab: "0",
|
activeTab: '0',
|
||||||
date: null,
|
date: null,
|
||||||
time: { start: '20:00', end: null },
|
time: { start: '20:00', end: null },
|
||||||
edit: false,
|
edit: false,
|
||||||
loading: false
|
loading: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: 'newEvent',
|
|
||||||
watch: {
|
watch: {
|
||||||
'time.start' (value) {
|
'time.start' (value) {
|
||||||
if (!value) return
|
if (!value) { return }
|
||||||
let [h, m] = value.split(':')
|
const [h, m] = value.split(':')
|
||||||
this.time.end = (Number(h) + 1) + ':' + m
|
this.time.end = (Number(h) + 1) + ':' + m
|
||||||
},
|
},
|
||||||
// month selected
|
// month selected
|
||||||
@@ -165,18 +166,6 @@ export default {
|
|||||||
this.updateEvents(this.page)
|
this.updateEvents(this.page)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async fetch ({ store, $axios }) {
|
|
||||||
try {
|
|
||||||
const now = new Date()
|
|
||||||
const events = await $axios.$get(`/event/${now.getMonth()}/${now.getFullYear()}`)
|
|
||||||
store.commit('setEvents', events)
|
|
||||||
const { tags, places } = await $axios.$get('/event/meta')
|
|
||||||
store.commit('update', { tags, places })
|
|
||||||
} catch(e) {
|
|
||||||
console.error('Error ', e)
|
|
||||||
}
|
|
||||||
moment.locale(store.state.locale)
|
|
||||||
},
|
|
||||||
async asyncData ({ params, $axios, error, store }) {
|
async asyncData ({ params, $axios, error, store }) {
|
||||||
if (params.edit) {
|
if (params.edit) {
|
||||||
const data = { time: {}, event: { place: {} } }
|
const data = { time: {}, event: { place: {} } }
|
||||||
@@ -216,6 +205,18 @@ export default {
|
|||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
async fetch ({ store, $axios }) {
|
||||||
|
try {
|
||||||
|
const now = new Date()
|
||||||
|
const events = await $axios.$get(`/event/${now.getMonth()}/${now.getFullYear()}`)
|
||||||
|
store.commit('setEvents', events)
|
||||||
|
const { tags, places } = await $axios.$get('/event/meta')
|
||||||
|
store.commit('update', { tags, places })
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error ', e)
|
||||||
|
}
|
||||||
|
moment.locale(store.state.locale)
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
tags: state => state.tags.map(t => t.tag),
|
tags: state => state.tags.map(t => t.tag),
|
||||||
@@ -227,7 +228,7 @@ export default {
|
|||||||
}),
|
}),
|
||||||
whenPatterns () {
|
whenPatterns () {
|
||||||
const dates = this.date
|
const dates = this.date
|
||||||
if (!dates || !dates.length) return
|
if (!dates || !dates.length) { return }
|
||||||
|
|
||||||
const freq = this.event.recurrent.frequency
|
const freq = this.event.recurrent.frequency
|
||||||
const weekDays = uniq(map(dates, date => moment(date).format('dddd')))
|
const weekDays = uniq(map(dates, date => moment(date).format('dddd')))
|
||||||
@@ -246,23 +247,23 @@ export default {
|
|||||||
},
|
},
|
||||||
todayEvents () {
|
todayEvents () {
|
||||||
if (this.event.type === 'multidate') {
|
if (this.event.type === 'multidate') {
|
||||||
if (!this.date || !this.date.start) return
|
if (!this.date || !this.date.start) { return }
|
||||||
const date_start = moment(this.date.start)
|
const date_start = moment(this.date.start)
|
||||||
const date_end = moment(this.date.end)
|
const date_end = moment(this.date.end)
|
||||||
return this.events.filter(e =>
|
return this.events.filter(e =>
|
||||||
!e.multidate ?
|
!e.multidate
|
||||||
date_start.isSame(moment.unix(e.start_datetime), 'day') ||
|
? date_start.isSame(moment.unix(e.start_datetime), 'day') ||
|
||||||
date_start.isBefore(moment.unix(e.start_datime)) && date_end.isAfter(moment.unix(e.start_datetime)) :
|
date_start.isBefore(moment.unix(e.start_datime)) && date_end.isAfter(moment.unix(e.start_datetime))
|
||||||
date_start.isSame(moment.unix(e.start_datetime), 'day') || date_start.isSame(moment.unix(e.end_datetime)) ||
|
: date_start.isSame(moment.unix(e.start_datetime), 'day') || date_start.isSame(moment.unix(e.end_datetime)) ||
|
||||||
date_start.isAfter(moment.unix(e.start_datetime)) && date_start.isBefore(moment.unix(e.end_datetime)))
|
date_start.isAfter(moment.unix(e.start_datetime)) && date_start.isBefore(moment.unix(e.end_datetime)))
|
||||||
} else if (this.event.type === 'recurrent') {
|
} else if (this.event.type === 'recurrent') {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const date = moment(this.date)
|
const date = moment(this.date)
|
||||||
return this.events.filter(e =>
|
return this.events.filter(e =>
|
||||||
!e.multidate ?
|
!e.multidate
|
||||||
!e.recurrent && date.isSame(moment.unix(e.start_datetime), 'day') :
|
? !e.recurrent && date.isSame(moment.unix(e.start_datetime), 'day')
|
||||||
moment.unix(e.start_datetime).isSame(date, 'day') ||
|
: moment.unix(e.start_datetime).isSame(date, 'day') ||
|
||||||
moment.unix(e.start_datetime).isBefore(date) && moment.unix(e.end_datetime).isAfter(date)
|
moment.unix(e.start_datetime).isBefore(date) && moment.unix(e.end_datetime).isAfter(date)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -278,7 +279,9 @@ export default {
|
|||||||
|
|
||||||
attributes = attributes.concat(this.filteredEvents
|
attributes = attributes.concat(this.filteredEvents
|
||||||
.filter(e => e.multidate && !e.recurrent)
|
.filter(e => e.multidate && !e.recurrent)
|
||||||
.map( e => ({ key: e.id, highlight: {}, dates: {
|
.map(e => ({ key: e.id,
|
||||||
|
highlight: {},
|
||||||
|
dates: {
|
||||||
start: moment.unix(e.start_datetime).toDate(), end: moment.unix(e.end_datetime).toDate() } })))
|
start: moment.unix(e.start_datetime).toDate(), end: moment.unix(e.end_datetime).toDate() } })))
|
||||||
|
|
||||||
return attributes
|
return attributes
|
||||||
@@ -297,7 +300,7 @@ export default {
|
|||||||
return this.event.place.name.length > 0 &&
|
return this.event.place.name.length > 0 &&
|
||||||
this.event.place.address.length > 0
|
this.event.place.address.length > 0
|
||||||
case 3 + t:
|
case 3 + t:
|
||||||
if (this.date && this.time.start) return true
|
if (this.date && this.time.start) { return true }
|
||||||
case 4 + t:
|
case 4 + t:
|
||||||
return this.event.place.name.length > 0 &&
|
return this.event.place.name.length > 0 &&
|
||||||
this.event.place.address.length > 0 &&
|
this.event.place.address.length > 0 &&
|
||||||
@@ -309,16 +312,13 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
...mapActions(['addEvent', 'updateEvent', 'updateMeta', 'updateEvents']),
|
...mapActions(['addEvent', 'updateEvent', 'updateMeta', 'updateEvents']),
|
||||||
recurrentDays () {
|
recurrentDays () {
|
||||||
if (this.event.type !== 'recurrent' || !this.date || !this.date.length) return
|
if (this.event.type !== 'recurrent' || !this.date || !this.date.length) { return }
|
||||||
const type = this.event.recurrent.type
|
const type = this.event.recurrent.type
|
||||||
if (type === 'ordinal')
|
if (type === 'ordinal') { return map(this.date, d => moment(d).date()) } else if (type === 'weekday') { return map(this.date, moment(d).day() + 1) }
|
||||||
return map(this.date, d => moment(d).date())
|
|
||||||
else if (type === 'weekday')
|
|
||||||
return map(this.date, moment(d).day()+1)
|
|
||||||
},
|
},
|
||||||
next () {
|
next () {
|
||||||
this.activeTab = String(Number(this.activeTab) + 1)
|
this.activeTab = String(Number(this.activeTab) + 1)
|
||||||
if (this.activeTab === "2") {
|
if (this.activeTab === '2') {
|
||||||
this.$refs.title.focus()
|
this.$refs.title.focus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -374,7 +374,7 @@ export default {
|
|||||||
const recurrent = {
|
const recurrent = {
|
||||||
frequency: this.event.recurrent.frequency,
|
frequency: this.event.recurrent.frequency,
|
||||||
days: this.event.recurrent.type === 'ordinal' ? map(this.date, d => moment(d).date()) : map(this.date, d => moment(d).day() + 1),
|
days: this.event.recurrent.type === 'ordinal' ? map(this.date, d => moment(d).date()) : map(this.date, d => moment(d).day() + 1),
|
||||||
type: this.event.recurrent.type,
|
type: this.event.recurrent.type
|
||||||
}
|
}
|
||||||
if (end_hour < start_hour) {
|
if (end_hour < start_hour) {
|
||||||
end_datetime = end_datetime.add(1, 'day')
|
end_datetime = end_datetime.add(1, 'day')
|
||||||
@@ -396,8 +396,7 @@ export default {
|
|||||||
if (this.edit) {
|
if (this.edit) {
|
||||||
formData.append('id', this.event.id)
|
formData.append('id', this.event.id)
|
||||||
}
|
}
|
||||||
if (this.event.tags)
|
if (this.event.tags) { this.event.tags.forEach(tag => formData.append('tags[]', tag)) }
|
||||||
this.event.tags.forEach(tag => formData.append('tags[]', tag))
|
|
||||||
try {
|
try {
|
||||||
if (this.edit) {
|
if (this.edit) {
|
||||||
await this.updateEvent(formData)
|
await this.updateEvent(formData)
|
||||||
@@ -412,7 +411,7 @@ export default {
|
|||||||
switch (e.request.status) {
|
switch (e.request.status) {
|
||||||
case 413:
|
case 413:
|
||||||
Message({ type: 'error', showClose: true, message: this.$t('event.image_too_big') })
|
Message({ type: 'error', showClose: true, message: this.$t('event.image_too_big') })
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
Message({ type: 'error', showClose: true, message: e })
|
Message({ type: 'error', showClose: true, message: e })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,6 @@
|
|||||||
el-form-item(v-show='allow_recurrent_event' :label="$t('admin.recurrent_event_visible')")
|
el-form-item(v-show='allow_recurrent_event' :label="$t('admin.recurrent_event_visible')")
|
||||||
el-switch(v-model='recurrent_event_visible')
|
el-switch(v-model='recurrent_event_visible')
|
||||||
|
|
||||||
|
|
||||||
el-divider {{$t('admin.federation')}}
|
el-divider {{$t('admin.federation')}}
|
||||||
el-form(inline label-width='400px')
|
el-form(inline label-width='400px')
|
||||||
el-form-item(:label="$t('admin.enable_federation')")
|
el-form-item(:label="$t('admin.enable_federation')")
|
||||||
@@ -91,21 +90,13 @@ export default {
|
|||||||
tag: { name: '', color: '' },
|
tag: { name: '', color: '' },
|
||||||
events: [],
|
events: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
tab: "0",
|
tab: '0',
|
||||||
open: true,
|
open: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
head () {
|
head () {
|
||||||
return { title: `${this.settings.title} - ${this.$t('common.admin')}` }
|
return { title: `${this.settings.title} - ${this.$t('common.admin')}` }
|
||||||
},
|
},
|
||||||
async mounted () {
|
|
||||||
const code = this.$route.query.code
|
|
||||||
|
|
||||||
if (code) {
|
|
||||||
this.tab = "4"
|
|
||||||
const instance = await this.$axios.$post('/user/code', {code, is_admin: true})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async asyncData ({ $axios, params, store }) {
|
async asyncData ({ $axios, params, store }) {
|
||||||
try {
|
try {
|
||||||
const users = await $axios.$get('/users')
|
const users = await $axios.$get('/users')
|
||||||
@@ -115,6 +106,14 @@ export default {
|
|||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async mounted () {
|
||||||
|
const code = this.$route.query.code
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
this.tab = '4'
|
||||||
|
const instance = await this.$axios.$post('/user/code', { code, is_admin: true })
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['tags', 'settings']),
|
...mapState(['tags', 'settings']),
|
||||||
allow_registration: {
|
allow_registration: {
|
||||||
@@ -144,7 +143,7 @@ export default {
|
|||||||
paginatedTags () {
|
paginatedTags () {
|
||||||
return this.tags.slice((this.tagPage - 1) * this.perPage,
|
return this.tags.slice((this.tagPage - 1) * this.perPage,
|
||||||
this.tagPage * this.perPage)
|
this.tagPage * this.perPage)
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['setSetting']),
|
...mapActions(['setSetting']),
|
||||||
@@ -167,7 +166,7 @@ export default {
|
|||||||
this.events = this.events.filter(e => e.id !== id)
|
this.events = this.events.filter(e => e.id !== id)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ export default {
|
|||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
|
||||||
let params = []
|
let params = []
|
||||||
if (places) params.push(`places=${places}`)
|
if (places) { params.push(`places=${places}`) }
|
||||||
if (tags) params.push(`tags=${tags}`)
|
if (tags) { params.push(`tags=${tags}`) }
|
||||||
|
|
||||||
params = params.length ? `?${params.join('&')}` : ''
|
params = params.length ? `?${params.join('&')}` : ''
|
||||||
const events = await $axios.$get(`/export/json${params}`)
|
const events = await $axios.$get(`/export/json${params}`)
|
||||||
|
|
||||||
return { events, title }
|
return { events, title }
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -72,14 +72,16 @@ export default {
|
|||||||
// },
|
// },
|
||||||
|
|
||||||
head () {
|
head () {
|
||||||
if (!this.event) return {}
|
if (!this.event) { return {} }
|
||||||
return {
|
return {
|
||||||
title: `${this.settings.title} - ${this.event.title}`,
|
title: `${this.settings.title} - ${this.event.title}`,
|
||||||
meta: [
|
meta: [
|
||||||
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
|
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
|
||||||
{ hid: 'description', name: 'description',
|
{ hid: 'description',
|
||||||
|
name: 'description',
|
||||||
content: this.event.description.slice(0, 1000) },
|
content: this.event.description.slice(0, 1000) },
|
||||||
{ hid: 'og-description', name: 'og:description',
|
{ hid: 'og-description',
|
||||||
|
name: 'og:description',
|
||||||
content: this.event.description.slice(0, 100) },
|
content: this.event.description.slice(0, 100) },
|
||||||
{ hid: 'og-title', property: 'og:title', content: this.event.title },
|
{ hid: 'og-title', property: 'og:title', content: this.event.title },
|
||||||
{ hid: 'og-url', property: 'og:url', content: `event/${this.event.id}` },
|
{ hid: 'og-url', property: 'og:url', content: `event/${this.event.id}` },
|
||||||
@@ -88,15 +90,6 @@ export default {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async fetch ({ $axios, store }) {
|
|
||||||
try {
|
|
||||||
const now = new Date()
|
|
||||||
const events = await $axios.$get(`/event/${now.getMonth()}/${now.getFullYear()}`)
|
|
||||||
return store.commit('setEvents', events)
|
|
||||||
} catch(e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async asyncData ({ $axios, params, error }) {
|
async asyncData ({ $axios, params, error }) {
|
||||||
try {
|
try {
|
||||||
const [ id, start_datetime ] = params.id.split('_')
|
const [ id, start_datetime ] = params.id.split('_')
|
||||||
@@ -108,16 +101,25 @@ export default {
|
|||||||
error({ statusCode: 404, message: 'Event not found' })
|
error({ statusCode: 404, message: 'Event not found' })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async fetch ({ $axios, store }) {
|
||||||
|
try {
|
||||||
|
const now = new Date()
|
||||||
|
const events = await $axios.$get(`/event/${now.getMonth()}/${now.getFullYear()}`)
|
||||||
|
return store.commit('setEvents', events)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['filteredEvents']),
|
...mapGetters(['filteredEvents']),
|
||||||
...mapState(['settings']),
|
...mapState(['settings']),
|
||||||
next () {
|
next () {
|
||||||
let found = false
|
let found = false
|
||||||
const event = this.filteredEvents.find(e => {
|
const event = this.filteredEvents.find(e => {
|
||||||
if (found) return e
|
if (found) { return e }
|
||||||
found = (e.start_datetime === this.event.start_datetime && e.id === this.event.id)
|
found = (e.start_datetime === this.event.start_datetime && e.id === this.event.id)
|
||||||
})
|
})
|
||||||
if (!event) return false
|
if (!event) { return false }
|
||||||
if (event.recurrent) {
|
if (event.recurrent) {
|
||||||
return `${event.id}_${event.start_datetime}`
|
return `${event.id}_${event.start_datetime}`
|
||||||
}
|
}
|
||||||
@@ -126,10 +128,10 @@ export default {
|
|||||||
prev () {
|
prev () {
|
||||||
let event = false
|
let event = false
|
||||||
this.filteredEvents.find(e => {
|
this.filteredEvents.find(e => {
|
||||||
if (e.start_datetime === this.event.start_datetime && e.id === this.event.id) return true
|
if (e.start_datetime === this.event.start_datetime && e.id === this.event.id) { return true }
|
||||||
event = e
|
event = e
|
||||||
})
|
})
|
||||||
if (!event) return false
|
if (!event) { return false }
|
||||||
if (event.recurrent) {
|
if (event.recurrent) {
|
||||||
return `${event.id}_${event.start_datetime}`
|
return `${event.id}_${event.start_datetime}`
|
||||||
}
|
}
|
||||||
@@ -139,9 +141,9 @@ export default {
|
|||||||
return this.event.image_path && '/media/' + this.event.image_path
|
return this.event.image_path && '/media/' + this.event.image_path
|
||||||
},
|
},
|
||||||
mine () {
|
mine () {
|
||||||
if (!this.$auth.user) return false
|
if (!this.$auth.user) { return false }
|
||||||
return this.event.userId === this.$auth.user.id || this.$auth.user.is_admin
|
return this.event.userId === this.$auth.user.id || this.$auth.user.is_admin
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['delEvent']),
|
...mapActions(['delEvent']),
|
||||||
@@ -149,7 +151,7 @@ export default {
|
|||||||
return value.replace(/<a.*href="([^">]+).*>(?:.(?!\<\/a\>))*.<\/a>/, (orig, url) => {
|
return value.replace(/<a.*href="([^">]+).*>(?:.(?!\<\/a\>))*.<\/a>/, (orig, url) => {
|
||||||
// get extension
|
// get extension
|
||||||
const ext = url.slice(-4)
|
const ext = url.slice(-4)
|
||||||
if (['.mp3', '.ogg'].indexOf(ext)>-1) {
|
if (['.mp3', '.ogg'].includes(ext)) {
|
||||||
return `<audio controls><source src='${url}'></audio>`
|
return `<audio controls><source src='${url}'></audio>`
|
||||||
} else {
|
} else {
|
||||||
return orig
|
return orig
|
||||||
@@ -164,7 +166,7 @@ export default {
|
|||||||
type: 'error' })
|
type: 'error' })
|
||||||
await this.$axios.delete(`/user/event/${this.id}`)
|
await this.$axios.delete(`/user/event/${this.id}`)
|
||||||
this.delEvent(Number(this.id))
|
this.delEvent(Number(this.id))
|
||||||
this.$router.replace("/")
|
this.$router.replace('/')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
@@ -247,4 +249,3 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
el-input.mb-1(type='textarea' v-model='listScript' readonly )
|
el-input.mb-1(type='textarea' v-model='listScript' readonly )
|
||||||
el-button.float-right(plain v-clipboard:copy='listScript' type='primary' icon='el-icon-document') {{$t('common.copy')}}
|
el-button.float-right(plain v-clipboard:copy='listScript' type='primary' icon='el-icon-document') {{$t('common.copy')}}
|
||||||
|
|
||||||
|
|
||||||
//- TOFIX
|
//- TOFIX
|
||||||
//- el-tab-pane.pt-1(label='calendar' name='calendar')
|
//- el-tab-pane.pt-1(label='calendar' name='calendar')
|
||||||
//- p(v-html='$t(`export.calendar_description`)')
|
//- p(v-html='$t(`export.calendar_description`)')
|
||||||
@@ -76,7 +75,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
type: 'feed',
|
type: 'feed',
|
||||||
notification: { email: '' },
|
notification: { email: '' },
|
||||||
list: { title: 'Gancio' },
|
list: { title: 'Gancio' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -94,7 +93,7 @@ export default {
|
|||||||
},
|
},
|
||||||
imgPath (event) {
|
imgPath (event) {
|
||||||
return event.image_path && event.image_path
|
return event.image_path && event.image_path
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['filters', 'events', 'settings']),
|
...mapState(['filters', 'events', 'settings']),
|
||||||
@@ -132,8 +131,8 @@ export default {
|
|||||||
return `${this.settings.baseurl}/api/export/${this.type}${query}`
|
return `${this.settings.baseurl}/api/export/${this.type}${query}`
|
||||||
},
|
},
|
||||||
showLink () {
|
showLink () {
|
||||||
return (['feed', 'ics'].indexOf(this.type)>-1)
|
return (['feed', 'ics'].includes(this.type))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -143,5 +142,3 @@ export default {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: mapState(['events']),
|
computed: mapState(['events']),
|
||||||
components: { Nav, Home },
|
components: { Nav, Home }
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState(['settings']),
|
...mapState(['settings']),
|
||||||
disabled () {
|
disabled () {
|
||||||
if (process.server) return false
|
if (process.server) { return false }
|
||||||
return !this.email || !this.password
|
return !this.email || !this.password
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
div(v-else) {{$t('recover.not_valid_code')}}
|
div(v-else) {{$t('recover.not_valid_code')}}
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
@@ -27,8 +26,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const valid = await $axios.$post('/user/check_recover_code', { recover_code: code })
|
const valid = await $axios.$post('/user/check_recover_code', { recover_code: code })
|
||||||
return { valid, code }
|
return { valid, code }
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
return { valid: false }
|
return { valid: false }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -53,5 +51,3 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState(['settings']),
|
...mapState(['settings']),
|
||||||
disabled () {
|
disabled () {
|
||||||
if (process.server) return false
|
if (process.server) { return false }
|
||||||
return !this.user.password || !this.user.email || !this.user.description
|
return !this.user.password || !this.user.email || !this.user.description
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -65,7 +65,7 @@ export default {
|
|||||||
message: this.$t(`register.${user.is_admin ? 'admin_' : ''}complete`),
|
message: this.$t(`register.${user.is_admin ? 'admin_' : ''}complete`),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
this.$router.replace("/")
|
this.$router.replace('/')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const error = get(e, 'response.data.errors[0].message', String(e))
|
const error = get(e, 'response.data.errors[0].message', String(e))
|
||||||
Message({
|
Message({
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ import { Message, MessageBox } from 'element-ui'
|
|||||||
import url from 'url'
|
import url from 'url'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'Settings',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
password: '',
|
password: '',
|
||||||
user: { }
|
user: { }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: 'Settings',
|
|
||||||
head () {
|
head () {
|
||||||
return {
|
return {
|
||||||
title: `${this.settings.title} - ${this.$t('common.settings')}`
|
title: `${this.settings.title} - ${this.$t('common.settings')}`
|
||||||
@@ -61,7 +61,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async change_password () {
|
async change_password () {
|
||||||
if (!this.password) return
|
if (!this.password) { return }
|
||||||
const user_data = { id: this.$auth.user.id, password: this.password }
|
const user_data = { id: this.$auth.user.id, password: this.password }
|
||||||
try {
|
try {
|
||||||
const user = await this.$axios.$put('/user', user_data)
|
const user = await this.$axios.$put('/user', user_data)
|
||||||
@@ -93,4 +93,3 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -27,5 +27,3 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'dayjs/locale/it'
|
|||||||
import 'dayjs/locale/es'
|
import 'dayjs/locale/es'
|
||||||
|
|
||||||
export default ({ app, store }) => {
|
export default ({ app, store }) => {
|
||||||
|
|
||||||
// replace links with anchors
|
// replace links with anchors
|
||||||
// TODO: remove fb tracking id
|
// TODO: remove fb tracking id
|
||||||
Vue.filter('linkify', value => value.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>'))
|
Vue.filter('linkify', value => value.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>'))
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export default async ({ app, store }) => {
|
|||||||
// This way we can use it in middleware and pages asyncData/fetch
|
// This way we can use it in middleware and pages asyncData/fetch
|
||||||
|
|
||||||
const user_locale = await app.$axios.$get('/settings/user_locale')
|
const user_locale = await app.$axios.$get('/settings/user_locale')
|
||||||
for(let lang in user_locale) {
|
for (const lang in user_locale) {
|
||||||
if (locales[lang]) merge(locales[lang], user_locale[lang])
|
if (locales[lang]) { merge(locales[lang], user_locale[lang]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
app.i18n = new VueI18n({
|
app.i18n = new VueI18n({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const { user: User } = require('./models')
|
|||||||
|
|
||||||
const Auth = {
|
const Auth = {
|
||||||
async fillUser (req, res, next) {
|
async fillUser (req, res, next) {
|
||||||
if (!req.user) return next()
|
if (!req.user) { return next() }
|
||||||
req.user = await User.findOne({
|
req.user = await User.findOne({
|
||||||
where: { id: { [Op.eq]: req.user.id }, is_active: true }
|
where: { id: { [Op.eq]: req.user.id }, is_active: true }
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
@@ -35,9 +35,9 @@ const Auth = {
|
|||||||
.status(403)
|
.status(403)
|
||||||
.send({ message: 'Failed to authenticate token ' })
|
.send({ message: 'Failed to authenticate token ' })
|
||||||
}
|
}
|
||||||
if (req.user.is_admin && req.user.is_active) return next()
|
if (req.user.is_admin && req.user.is_active) { return next() }
|
||||||
return res.status(403).send({ message: 'Admin needed' })
|
return res.status(403).send({ message: 'Admin needed' })
|
||||||
},
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const eventController = {
|
|||||||
order: [['weigth', 'DESC']],
|
order: [['weigth', 'DESC']],
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: ['createdAt', 'updatedAt']
|
exclude: ['createdAt', 'updatedAt']
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
res.json({ tags, places })
|
res.json({ tags, places })
|
||||||
@@ -45,16 +45,16 @@ const eventController = {
|
|||||||
async getNotifications (event) {
|
async getNotifications (event) {
|
||||||
function match (event, filters) {
|
function match (event, filters) {
|
||||||
// matches if no filter specified
|
// matches if no filter specified
|
||||||
if (!filters) return true
|
if (!filters) { return true }
|
||||||
|
|
||||||
// check for visibility
|
// check for visibility
|
||||||
if (typeof filters.is_visible !== 'undefined' && filters.is_visible !== event.is_visible) return false
|
if (typeof filters.is_visible !== 'undefined' && filters.is_visible !== event.is_visible) { return false }
|
||||||
|
|
||||||
if (!filters.tags && !filters.places) return true
|
if (!filters.tags && !filters.places) { return true }
|
||||||
if (!filters.tags.length && !filters.places.length) return true
|
if (!filters.tags.length && !filters.places.length) { return true }
|
||||||
if (filters.tags.length) {
|
if (filters.tags.length) {
|
||||||
const m = lodash.intersection(event.tags.map(t => t.tag), filters.tags)
|
const m = lodash.intersection(event.tags.map(t => t.tag), filters.tags)
|
||||||
if (m.length > 0) return true
|
if (m.length > 0) { return true }
|
||||||
}
|
}
|
||||||
if (filters.places.length) {
|
if (filters.places.length) {
|
||||||
if (filters.places.find(p => p === event.place.name)) {
|
if (filters.places.find(p => p === event.place.name)) {
|
||||||
@@ -88,7 +88,7 @@ const eventController = {
|
|||||||
async get (req, res) {
|
async get (req, res) {
|
||||||
const is_admin = req.user && req.user.is_admin
|
const is_admin = req.user && req.user.is_admin
|
||||||
const id = req.params.event_id
|
const id = req.params.event_id
|
||||||
let event = await Event.findByPk(id, {
|
const event = await Event.findByPk(id, {
|
||||||
plain: true,
|
plain: true,
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: ['createdAt', 'updatedAt']
|
exclude: ['createdAt', 'updatedAt']
|
||||||
@@ -112,7 +112,7 @@ const eventController = {
|
|||||||
async confirm (req, res) {
|
async confirm (req, res) {
|
||||||
const id = Number(req.params.event_id)
|
const id = Number(req.params.event_id)
|
||||||
const event = await Event.findByPk(id)
|
const event = await Event.findByPk(id)
|
||||||
if (!event) return res.sendStatus(404)
|
if (!event) { return res.sendStatus(404) }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
event.is_visible = true
|
event.is_visible = true
|
||||||
@@ -131,7 +131,7 @@ const eventController = {
|
|||||||
async unconfirm (req, res) {
|
async unconfirm (req, res) {
|
||||||
const id = Number(req.params.event_id)
|
const id = Number(req.params.event_id)
|
||||||
const event = await Event.findByPk(id)
|
const event = await Event.findByPk(id)
|
||||||
if (!event) return sendStatus(404)
|
if (!event) { return sendStatus(404) }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
event.is_visible = false
|
event.is_visible = false
|
||||||
@@ -193,7 +193,7 @@ const eventController = {
|
|||||||
.endOf('month')
|
.endOf('month')
|
||||||
|
|
||||||
const shownDays = end.diff(start, 'days')
|
const shownDays = end.diff(start, 'days')
|
||||||
if (shownDays <= 35) end = end.add(1, 'week')
|
if (shownDays <= 35) { end = end.add(1, 'week') }
|
||||||
end = end.endOf('week')
|
end = end.endOf('week')
|
||||||
|
|
||||||
let events = await Event.findAll({
|
let events = await Event.findAll({
|
||||||
@@ -226,7 +226,7 @@ const eventController = {
|
|||||||
function createEventsFromRecurrent (e, dueTo = null) {
|
function createEventsFromRecurrent (e, dueTo = null) {
|
||||||
const events = []
|
const events = []
|
||||||
const recurrent = JSON.parse(e.recurrent)
|
const recurrent = JSON.parse(e.recurrent)
|
||||||
if (!recurrent.frequency) return false
|
if (!recurrent.frequency) { return false }
|
||||||
|
|
||||||
let cursor = moment(start).startOf('week')
|
let cursor = moment(start).startOf('week')
|
||||||
const start_date = moment.unix(e.start_datetime)
|
const start_date = moment.unix(e.start_datetime)
|
||||||
@@ -244,10 +244,10 @@ const eventController = {
|
|||||||
cursor.add(days[0] - 1, 'day')
|
cursor.add(days[0] - 1, 'day')
|
||||||
if (frequency === '2w') {
|
if (frequency === '2w') {
|
||||||
const nWeeks = cursor.diff(e.start_datetime, 'w') % 2
|
const nWeeks = cursor.diff(e.start_datetime, 'w') % 2
|
||||||
if (!nWeeks) cursor.add(1, 'week')
|
if (!nWeeks) { cursor.add(1, 'week') }
|
||||||
}
|
}
|
||||||
toAdd.n = Number(frequency[0])
|
toAdd.n = Number(frequency[0])
|
||||||
toAdd.unit = 'week';
|
toAdd.unit = 'week'
|
||||||
// cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
// cursor.set('hour', start_date.hour()).set('minute', start_date.minutes())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,31 +265,29 @@ const eventController = {
|
|||||||
|
|
||||||
// add event at specified frequency
|
// add event at specified frequency
|
||||||
while (true) {
|
while (true) {
|
||||||
let first_event_of_week = cursor.clone()
|
const first_event_of_week = cursor.clone()
|
||||||
days.forEach(d => {
|
days.forEach(d => {
|
||||||
if (type === 'ordinal') {
|
if (type === 'ordinal') {
|
||||||
cursor.date(d)
|
cursor.date(d)
|
||||||
} else {
|
} else {
|
||||||
cursor.day(d - 1)
|
cursor.day(d - 1)
|
||||||
}
|
}
|
||||||
if (cursor.isAfter(dueTo) || cursor.isBefore(start)) return
|
if (cursor.isAfter(dueTo) || cursor.isBefore(start)) { return }
|
||||||
e.start_datetime = cursor.unix()
|
e.start_datetime = cursor.unix()
|
||||||
e.end_datetime = e.start_datetime + duration
|
e.end_datetime = e.start_datetime + duration
|
||||||
events.push(Object.assign({}, e))
|
events.push(Object.assign({}, e))
|
||||||
})
|
})
|
||||||
if (cursor.isAfter(dueTo)) break
|
if (cursor.isAfter(dueTo)) { break }
|
||||||
cursor = first_event_of_week.add(toAdd.n, toAdd.unit)
|
cursor = first_event_of_week.add(toAdd.n, toAdd.unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
let allEvents = events.filter(e => !e.recurrent)
|
let allEvents = events.filter(e => !e.recurrent)
|
||||||
events.filter(e => e.recurrent).forEach(e => {
|
events.filter(e => e.recurrent).forEach(e => {
|
||||||
const events = createEventsFromRecurrent(e, end)
|
const events = createEventsFromRecurrent(e, end)
|
||||||
if (events)
|
if (events) { allEvents = allEvents.concat(events) }
|
||||||
allEvents = allEvents.concat(events)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// allEvents.sort((a,b) => a.start_datetime-b.start_datetime)
|
// allEvents.sort((a,b) => a.start_datetime-b.start_datetime)
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ const userController = {
|
|||||||
eventDetails.image_path = req.file.filename
|
eventDetails.image_path = req.file.filename
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = await Event.create(eventDetails)
|
const event = await Event.create(eventDetails)
|
||||||
|
|
||||||
// create place if needed
|
// create place if needed
|
||||||
let place
|
let place
|
||||||
@@ -118,14 +118,12 @@ const userController = {
|
|||||||
// send response to client
|
// send response to client
|
||||||
res.json(event)
|
res.json(event)
|
||||||
|
|
||||||
if (req.user)
|
if (req.user) { federation.sendEvent(event, req.user) }
|
||||||
federation.sendEvent(event, req.user)
|
|
||||||
|
|
||||||
// res.sendStatus(200)
|
// res.sendStatus(200)
|
||||||
|
|
||||||
// send notification (mastodon/email/confirmation)
|
// send notification (mastodon/email/confirmation)
|
||||||
// notifier.notifyEvent(event.id)
|
// notifier.notifyEvent(event.id)
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateEvent (req, res) {
|
async updateEvent (req, res) {
|
||||||
@@ -171,7 +169,7 @@ const userController = {
|
|||||||
async forgotPassword (req, res) {
|
async forgotPassword (req, res) {
|
||||||
const email = req.body.email
|
const email = req.body.email
|
||||||
const user = await User.findOne({ where: { email: { [Op.eq]: email } } })
|
const user = await User.findOne({ where: { email: { [Op.eq]: email } } })
|
||||||
if (!user) return res.sendStatus(200)
|
if (!user) { return res.sendStatus(200) }
|
||||||
|
|
||||||
user.recover_code = crypto.randomBytes(16).toString('hex')
|
user.recover_code = crypto.randomBytes(16).toString('hex')
|
||||||
mail.send(user.email, 'recover', { user, config })
|
mail.send(user.email, 'recover', { user, config })
|
||||||
@@ -182,9 +180,9 @@ const userController = {
|
|||||||
|
|
||||||
async checkRecoverCode (req, res) {
|
async checkRecoverCode (req, res) {
|
||||||
const recover_code = req.body.recover_code
|
const recover_code = req.body.recover_code
|
||||||
if (!recover_code) return res.sendStatus(400)
|
if (!recover_code) { return res.sendStatus(400) }
|
||||||
const user = await User.findOne({ where: { recover_code: { [Op.eq]: recover_code } } })
|
const user = await User.findOne({ where: { recover_code: { [Op.eq]: recover_code } } })
|
||||||
if (!user) return res.sendStatus(400)
|
if (!user) { return res.sendStatus(400) }
|
||||||
try {
|
try {
|
||||||
await user.update({ recover_code: '' })
|
await user.update({ recover_code: '' })
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
@@ -196,9 +194,9 @@ const userController = {
|
|||||||
async updatePasswordWithRecoverCode (req, res) {
|
async updatePasswordWithRecoverCode (req, res) {
|
||||||
const recover_code = req.body.recover_code
|
const recover_code = req.body.recover_code
|
||||||
const password = req.body.password
|
const password = req.body.password
|
||||||
if (!recover_code || !password) return res.sendStatus(400)
|
if (!recover_code || !password) { return res.sendStatus(400) }
|
||||||
const user = await User.findOne({ where: { recover_code: { [Op.eq]: recover_code } } })
|
const user = await User.findOne({ where: { recover_code: { [Op.eq]: recover_code } } })
|
||||||
if (!user) return res.sendStatus(400)
|
if (!user) { return res.sendStatus(400) }
|
||||||
user.recover_code = ''
|
user.recover_code = ''
|
||||||
user.password = password
|
user.password = password
|
||||||
try {
|
try {
|
||||||
@@ -224,7 +222,7 @@ const userController = {
|
|||||||
// user to modify
|
// user to modify
|
||||||
user = await User.findByPk(req.body.id)
|
user = await User.findByPk(req.body.id)
|
||||||
|
|
||||||
if (!user) return res.status(404).json({ success: false, message: 'User not found!' })
|
if (!user) { return res.status(404).json({ success: false, message: 'User not found!' }) }
|
||||||
|
|
||||||
if (req.body.id !== req.user.id && !req.user.is_admin) {
|
if (req.body.id !== req.user.id && !req.user.is_admin) {
|
||||||
return res.status(400).json({ succes: false, message: 'Not allowed' })
|
return res.status(400).json({ succes: false, message: 'Not allowed' })
|
||||||
@@ -233,8 +231,7 @@ const userController = {
|
|||||||
// ensure username to not change if not empty
|
// ensure username to not change if not empty
|
||||||
req.body.username = user.username ? user.username : req.body.username
|
req.body.username = user.username ? user.username : req.body.username
|
||||||
|
|
||||||
if (!req.body.password)
|
if (!req.body.password) { delete req.body.password }
|
||||||
delete req.body.password
|
|
||||||
|
|
||||||
await user.update(req.body)
|
await user.update(req.body)
|
||||||
|
|
||||||
@@ -244,9 +241,8 @@ const userController = {
|
|||||||
res.json(user)
|
res.json(user)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
async register (req, res) {
|
async register (req, res) {
|
||||||
if (!settingsController.settings.allow_registration) return res.sendStatus(404)
|
if (!settingsController.settings.allow_registration) { return res.sendStatus(404) }
|
||||||
const n_users = await User.count()
|
const n_users = await User.count()
|
||||||
try {
|
try {
|
||||||
// the first registered user will be an active admin
|
// the first registered user will be an active admin
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ const settingsController = require('./controller/settings')
|
|||||||
const storage = require('./storage')
|
const storage = require('./storage')
|
||||||
const upload = multer({ storage })
|
const upload = multer({ storage })
|
||||||
|
|
||||||
|
const debug = require('debug')('api')
|
||||||
|
|
||||||
const api = express.Router()
|
const api = express.Router()
|
||||||
api.use(cookieParser())
|
api.use(cookieParser())
|
||||||
api.use(bodyParser.urlencoded({ extended: false }))
|
api.use(bodyParser.urlencoded({ extended: false }))
|
||||||
@@ -24,10 +26,10 @@ const jwt = expressJwt({
|
|||||||
credentialsRequired: false,
|
credentialsRequired: false,
|
||||||
getToken: function fromHeaderOrQuerystring (req) {
|
getToken: function fromHeaderOrQuerystring (req) {
|
||||||
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
|
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
|
||||||
return req.headers.authorization.split(' ')[1];
|
return req.headers.authorization.split(' ')[1]
|
||||||
} else if (req.cookies && req.cookies['auth._token.local']) {
|
} else if (req.cookies && req.cookies['auth._token.local']) {
|
||||||
const [ prefix, token ] = req.cookies['auth._token.local'].split(' ')
|
const [ prefix, token ] = req.cookies['auth._token.local'].split(' ')
|
||||||
if (prefix === 'Bearer') return token
|
if (prefix === 'Bearer') { return token }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -100,4 +102,16 @@ api.get('/export/:type', exportController.export)
|
|||||||
api.get('/event/:month/:year', eventController.getAll)
|
api.get('/event/:month/:year', eventController.getAll)
|
||||||
|
|
||||||
|
|
||||||
|
// Handle 404
|
||||||
|
api.use((req, res) => {
|
||||||
|
debug('404 Page not found: %s', req.path)
|
||||||
|
res.status(404).send('404: Page not Found')
|
||||||
|
})
|
||||||
|
|
||||||
|
// Handle 500
|
||||||
|
api.use((error, req, res, next) => {
|
||||||
|
debug(error)
|
||||||
|
res.status(500).send('500: Internal Server Error')
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = api
|
module.exports = api
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const mail = {
|
|||||||
updateFiles: false,
|
updateFiles: false,
|
||||||
defaultLocale: settings.locale,
|
defaultLocale: settings.locale,
|
||||||
locale: settings.locale,
|
locale: settings.locale,
|
||||||
locales: ['it', 'es'],
|
locales: ['it', 'es']
|
||||||
},
|
},
|
||||||
transport: config.smtp
|
transport: config.smtp
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
activitypub_id: {
|
activitypub_id: {
|
||||||
type: DataTypes.STRING(18),
|
type: DataTypes.STRING(18),
|
||||||
index: true,
|
index: true,
|
||||||
unique: true,
|
unique: true
|
||||||
},
|
},
|
||||||
data: DataTypes.JSON
|
data: DataTypes.JSON
|
||||||
}, {})
|
}, {})
|
||||||
@@ -12,4 +12,4 @@
|
|||||||
comment.belongsTo(models.event)
|
comment.belongsTo(models.event)
|
||||||
}
|
}
|
||||||
return comment
|
return comment
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
id: {
|
id: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
autoIncrement: true,
|
autoIncrement: true
|
||||||
},
|
},
|
||||||
title: DataTypes.STRING,
|
title: DataTypes.STRING,
|
||||||
slug: DataTypes.STRING,
|
slug: DataTypes.STRING,
|
||||||
@@ -45,7 +45,7 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
${this.description.length > 200 ? this.description.substr(0, 200) + '...' : this.description}<br/>
|
${this.description.length > 200 ? this.description.substr(0, 200) + '...' : this.description}<br/>
|
||||||
${tags} <br/>`
|
${tags} <br/>`
|
||||||
|
|
||||||
let attachment = []
|
const attachment = []
|
||||||
if (this.image_path) {
|
if (this.image_path) {
|
||||||
attachment.push({
|
attachment.push({
|
||||||
type: 'Document',
|
type: 'Document',
|
||||||
@@ -62,19 +62,22 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
// actor: `${config.baseurl}/federation/u/${username}`,
|
// actor: `${config.baseurl}/federation/u/${username}`,
|
||||||
// url: `${config.baseurl}/federation/m/${this.id}`,
|
// url: `${config.baseurl}/federation/m/${this.id}`,
|
||||||
// object: {
|
// object: {
|
||||||
|
type: 'Note',
|
||||||
|
id: `${config.baseurl}/federation/m/${this.id}`,
|
||||||
|
url: `${config.baseurl}/federation/m/${this.id}`,
|
||||||
attachment,
|
attachment,
|
||||||
tag: this.tags.map(tag => ({
|
tag: this.tags.map(tag => ({
|
||||||
type: 'Hashtag',
|
type: 'Hashtag',
|
||||||
name: '#' + tag.tag
|
name: '#' + tag.tag
|
||||||
})),
|
})),
|
||||||
id: `${config.baseurl}/federation/m/${this.id}`,
|
|
||||||
type: 'Note',
|
|
||||||
published: this.createdAt,
|
published: this.createdAt,
|
||||||
attributedTo: `${config.baseurl}/federation/u/${username}`,
|
attributedTo: `${config.baseurl}/federation/u/${username}`,
|
||||||
to: 'https://www.w3.org/ns/activitystreams#Public',
|
to: ['https://www.w3.org/ns/activitystreams#Public'],
|
||||||
cc: follower ? follower: [],
|
cc: follower || [],
|
||||||
content
|
content,
|
||||||
}
|
summary: null,
|
||||||
|
sensitive: false,
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,4 +32,3 @@ fs
|
|||||||
db.Sequelize = Sequelize
|
db.Sequelize = Sequelize
|
||||||
|
|
||||||
module.exports = db
|
module.exports = db
|
||||||
|
|
||||||
@@ -3,7 +3,8 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
const place = sequelize.define('place', {
|
const place = sequelize.define('place', {
|
||||||
name: {
|
name: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
unique: true, index: true,
|
unique: true,
|
||||||
|
index: true,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
address: DataTypes.STRING
|
address: DataTypes.STRING
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return tag
|
return tag
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.prototype.comparePassword = async function (pwd) {
|
user.prototype.comparePassword = async function (pwd) {
|
||||||
if (!this.password) return false
|
if (!this.password) { return false }
|
||||||
const ret = await bcrypt.compare(pwd, this.password)
|
const ret = await bcrypt.compare(pwd, this.password)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@@ -78,4 +78,4 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return user
|
return user
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ module.exports = {
|
|||||||
console.error('inReplyTo', inReplyTo)
|
console.error('inReplyTo', inReplyTo)
|
||||||
console.error('match', match)
|
console.error('match', match)
|
||||||
if (!match || match.length < 2) {
|
if (!match || match.length < 2) {
|
||||||
debug("Comment not found %s", inReplyTo)
|
debug('Comment not found %s', inReplyTo)
|
||||||
return res.status(404).send('Event not found!')
|
return res.status(404).send('Event not found!')
|
||||||
}
|
}
|
||||||
let event = await Event.findByPk(Number(match[1]))
|
let event = await Event.findByPk(Number(match[1]))
|
||||||
@@ -20,7 +20,7 @@ module.exports = {
|
|||||||
if (!event) {
|
if (!event) {
|
||||||
// in reply to another comment...
|
// in reply to another comment...
|
||||||
const comment = await Comment.findOne({ where: { activitypub_id: inReplyTo }, include: [Event] })
|
const comment = await Comment.findOne({ where: { activitypub_id: inReplyTo }, include: [Event] })
|
||||||
if (!comment) return res.status(404).send('Not found')
|
if (!comment) { return res.status(404).send('Not found') }
|
||||||
event = comment.event
|
event = comment.event
|
||||||
}
|
}
|
||||||
debug('comment from %s to "%s"', req.body.actor, event.title)
|
debug('comment from %s to "%s"', req.body.actor, event.title)
|
||||||
|
|||||||
@@ -5,20 +5,20 @@ const debug = require('debug')('fediverse:ego')
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
async boost (req, res) {
|
async boost (req, res) {
|
||||||
const match = req.body.object.match(`${config.baseurl}/federation/m/(.*)`)
|
const match = req.body.object.match(`${config.baseurl}/federation/m/(.*)`)
|
||||||
if (!match || match.length<2) return res.status(404).send('Event not found!')
|
if (!match || match.length < 2) { return res.status(404).send('Event not found!') }
|
||||||
debug('boost %s', match[1])
|
debug('boost %s', match[1])
|
||||||
const event = await Event.findByPk(Number(match[1]))
|
const event = await Event.findByPk(Number(match[1]))
|
||||||
if (!event) return res.status(404).send('Event not found!')
|
if (!event) { return res.status(404).send('Event not found!') }
|
||||||
await event.update({ boost: [...event.boost, req.body.actor] })
|
await event.update({ boost: [...event.boost, req.body.actor] })
|
||||||
res.sendStatus(201)
|
res.sendStatus(201)
|
||||||
},
|
},
|
||||||
|
|
||||||
async bookmark (req, res) {
|
async bookmark (req, res) {
|
||||||
const match = req.body.object.match(`${config.baseurl}/federation/m/(.*)`)
|
const match = req.body.object.match(`${config.baseurl}/federation/m/(.*)`)
|
||||||
if (!match || match.length<2) return res.status(404).send('Event not found!')
|
if (!match || match.length < 2) { return res.status(404).send('Event not found!') }
|
||||||
const event = await Event.findByPk(Number(match[1]))
|
const event = await Event.findByPk(Number(match[1]))
|
||||||
debug('%s bookmark %s (%d)', req.body.actor, event.title, event.likes.length)
|
debug('%s bookmark %s (%d)', req.body.actor, event.title, event.likes.length)
|
||||||
if (!event) return res.status(404).send('Event not found!')
|
if (!event) { return res.status(404).send('Event not found!') }
|
||||||
await event.update({ likes: [...event.likes, req.body.actor] })
|
await event.update({ likes: [...event.likes, req.body.actor] })
|
||||||
res.sendStatus(201)
|
res.sendStatus(201)
|
||||||
},
|
},
|
||||||
@@ -27,10 +27,10 @@ module.exports = {
|
|||||||
const body = req.body
|
const body = req.body
|
||||||
const object = body.object
|
const object = body.object
|
||||||
const match = object.object.match(`${config.baseurl}/federation/m/(.*)`)
|
const match = object.object.match(`${config.baseurl}/federation/m/(.*)`)
|
||||||
if (!match || match.length<2) return res.status(404).send('Event not found!')
|
if (!match || match.length < 2) { return res.status(404).send('Event not found!') }
|
||||||
const event = await Event.findByPk(Number(match[1]))
|
const event = await Event.findByPk(Number(match[1]))
|
||||||
debug('%s unbookmark %s (%d)', body.actor, event.title, event.likes.length)
|
debug('%s unbookmark %s (%d)', body.actor, event.title, event.likes.length)
|
||||||
if (!event) return res.status(404).send('Event not found!')
|
if (!event) { return res.status(404).send('Event not found!') }
|
||||||
await event.update({ likes: [...event.likes.filter(actor => actor !== body.actor)] })
|
await event.update({ likes: [...event.likes.filter(actor => actor !== body.actor)] })
|
||||||
res.sendStatus(201)
|
res.sendStatus(201)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,25 +8,25 @@ module.exports = {
|
|||||||
// follow request from fediverse
|
// follow request from fediverse
|
||||||
async follow (req, res) {
|
async follow (req, res) {
|
||||||
const body = req.body
|
const body = req.body
|
||||||
if (typeof body.object !== 'string') return
|
if (typeof body.object !== 'string') { return }
|
||||||
const username = body.object.replace(`${config.baseurl}/federation/u/`, '')
|
const username = body.object.replace(`${config.baseurl}/federation/u/`, '')
|
||||||
const user = await User.findOne({ where: { username } })
|
const user = await User.findOne({ where: { username } })
|
||||||
if (!user) return res.status(404).send('User not found')
|
if (!user) { return res.status(404).send('User not found') }
|
||||||
|
|
||||||
// check for duplicate
|
// check for duplicate
|
||||||
if (user.followers.indexOf(body.actor) === -1) {
|
if (!user.followers.includes(body.actor)) {
|
||||||
await user.update({ followers: [...user.followers, body.actor] })
|
await user.update({ followers: [...user.followers, body.actor] })
|
||||||
debug('%s followed by %s (%d)', username, body.actor, user.followers.length)
|
debug('%s followed by %s (%d)', username, body.actor, user.followers.length)
|
||||||
} else {
|
} else {
|
||||||
debug('duplicate %s followed by %s', username, body.actor)
|
debug('duplicate %s followed by %s', username, body.actor)
|
||||||
}
|
}
|
||||||
const guid = crypto.randomBytes(16).toString('hex')
|
const guid = crypto.randomBytes(16).toString('hex')
|
||||||
let message = {
|
const message = {
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
'id': `${config.baseurl}/federation/${guid}`,
|
'id': `${config.baseurl}/federation/${guid}`,
|
||||||
'type': 'Accept',
|
'type': 'Accept',
|
||||||
'actor': `${config.baseurl}/federation/u/${user.username}`,
|
'actor': `${config.baseurl}/federation/u/${user.username}`,
|
||||||
'object': body,
|
'object': body
|
||||||
}
|
}
|
||||||
Helpers.signAndSend(message, user, body.actor)
|
Helpers.signAndSend(message, user, body.actor)
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
@@ -37,7 +37,7 @@ module.exports = {
|
|||||||
const body = req.body
|
const body = req.body
|
||||||
const username = body.object.object.replace(`${config.baseurl}/federation/u/`, '')
|
const username = body.object.object.replace(`${config.baseurl}/federation/u/`, '')
|
||||||
const user = await User.findOne({ where: { username } })
|
const user = await User.findOne({ where: { username } })
|
||||||
if (!user) return res.status(404).send('User not found')
|
if (!user) { return res.status(404).send('User not found') }
|
||||||
|
|
||||||
if (body.actor !== body.object.actor) {
|
if (body.actor !== body.object.actor) {
|
||||||
debug('Unfollow an user created by a different actor !?!?')
|
debug('Unfollow an user created by a different actor !?!?')
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ const Helpers = {
|
|||||||
},
|
},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(message) })
|
body: JSON.stringify(message) })
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async sendEvent (event, user) {
|
async sendEvent (event, user) {
|
||||||
@@ -48,7 +47,7 @@ const Helpers = {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let follower of instanceAdmin.followers) {
|
for (const follower of instanceAdmin.followers) {
|
||||||
debug('Notify %s with event %s', follower, event.title)
|
debug('Notify %s with event %s', follower, event.title)
|
||||||
const body = {
|
const body = {
|
||||||
id: `${config.baseurl}/federation/m/c_${event.id}`,
|
id: `${config.baseurl}/federation/m/c_${event.id}`,
|
||||||
@@ -67,14 +66,16 @@ const Helpers = {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.settings.enable_federation || !user.username) return
|
if (!user.settings.enable_federation || !user.username) { return }
|
||||||
for(let follower of user.followers) {
|
for (const follower of user.followers) {
|
||||||
debug('Notify %s with event %s', follower, event.title)
|
debug('Notify %s with event %s', follower, event.title)
|
||||||
const body = {
|
const body = {
|
||||||
id: `${config.baseurl}/federation/m/c_${event.id}`,
|
id: `${config.baseurl}/federation/m/${event.id}#create`,
|
||||||
type: 'Create',
|
type: 'Create',
|
||||||
|
to: ['https://www.w3.org/ns/activitystreams#Public'],
|
||||||
|
cc: [`${config.baseurl}/federation/u/${user.username}/followers`],
|
||||||
|
published: event.createdAt,
|
||||||
actor: `${config.baseurl}/federation/u/${user.username}`,
|
actor: `${config.baseurl}/federation/u/${user.username}`,
|
||||||
url: `${config.baseurl}/federation/m/${event.id}`,
|
|
||||||
object: event.toAP(user.username, follower)
|
object: event.toAP(user.username, follower)
|
||||||
}
|
}
|
||||||
body['@context'] = 'https://www.w3.org/ns/activitystreams'
|
body['@context'] = 'https://www.w3.org/ns/activitystreams'
|
||||||
@@ -92,7 +93,7 @@ const Helpers = {
|
|||||||
// TODO: cache
|
// TODO: cache
|
||||||
async getActor (url, force = false) {
|
async getActor (url, force = false) {
|
||||||
// try with cache first
|
// try with cache first
|
||||||
if (!force && actorCache[url]) return actorCache[url]
|
if (!force && actorCache[url]) { return actorCache[url] }
|
||||||
const user = await fetch(url, { headers: { 'Accept': 'application/jrd+json, application/json' } })
|
const user = await fetch(url, { headers: { 'Accept': 'application/jrd+json, application/json' } })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@@ -108,7 +109,7 @@ const Helpers = {
|
|||||||
// ref: https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
|
// ref: https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
|
||||||
async verifySignature (req, res, next) {
|
async verifySignature (req, res, next) {
|
||||||
let user = await Helpers.getActor(req.body.actor)
|
let user = await Helpers.getActor(req.body.actor)
|
||||||
if (!user) return res.status(401).send('Actor not found')
|
if (!user) { return res.status(401).send('Actor not found') }
|
||||||
|
|
||||||
// little hack -> https://github.com/joyent/node-http-signature/pull/83
|
// little hack -> https://github.com/joyent/node-http-signature/pull/83
|
||||||
req.headers.authorization = 'Signature ' + req.headers.signature
|
req.headers.authorization = 'Signature ' + req.headers.signature
|
||||||
@@ -117,12 +118,12 @@ const Helpers = {
|
|||||||
// https://github.com/joyent/node-http-signature/issues/87
|
// https://github.com/joyent/node-http-signature/issues/87
|
||||||
req.url = '/federation' + req.url
|
req.url = '/federation' + req.url
|
||||||
const parsed = httpSignature.parseRequest(req)
|
const parsed = httpSignature.parseRequest(req)
|
||||||
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) return next()
|
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) { return next() }
|
||||||
|
|
||||||
// signature not valid, try without cache
|
// signature not valid, try without cache
|
||||||
user = await Helpers.getActor(req.body.actor, true)
|
user = await Helpers.getActor(req.body.actor, true)
|
||||||
if (!user) return res.status(401).send('Actor not found')
|
if (!user) { return res.status(401).send('Actor not found') }
|
||||||
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) return next()
|
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) { return next() }
|
||||||
|
|
||||||
// still not valid
|
// still not valid
|
||||||
debug('Invalid signature from user %s', req.body.actor)
|
debug('Invalid signature from user %s', req.body.actor)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const { event: Event, user: User, tag: Tag, place: Place } = require('../api/mod
|
|||||||
const Comments = require('./comments')
|
const Comments = require('./comments')
|
||||||
const Helpers = require('./helpers')
|
const Helpers = require('./helpers')
|
||||||
const Ego = require('./ego')
|
const Ego = require('./ego')
|
||||||
|
const debug = require('debug')('federation')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Federation is calling!
|
* Federation is calling!
|
||||||
@@ -16,22 +17,20 @@ const Ego = require('./ego')
|
|||||||
router.use(cors())
|
router.use(cors())
|
||||||
router.use(express.json({ type: ['application/json', 'application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'] }))
|
router.use(express.json({ type: ['application/json', 'application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'] }))
|
||||||
|
|
||||||
|
|
||||||
router.get('/m/:event_id', async (req, res) => {
|
router.get('/m/:event_id', async (req, res) => {
|
||||||
const event_id = req.params.event_id
|
const event_id = req.params.event_id
|
||||||
// if (req.accepts('html')) return res.redirect(301, `/event/${event_id}`)
|
// if (req.accepts('html')) return res.redirect(301, `/event/${event_id}`)
|
||||||
|
|
||||||
const event = await Event.findByPk(req.params.event_id, { include: [ User, Tag, Place ] })
|
const event = await Event.findByPk(req.params.event_id, { include: [ User, Tag, Place ] })
|
||||||
if (!event) return res.status(404).send('Not found')
|
if (!event) { return res.status(404).send('Not found') }
|
||||||
return res.json(event.toAP(event.user.username))
|
return res.json(event.toAP(event.user.username))
|
||||||
})
|
})
|
||||||
|
|
||||||
// get any message coming from federation
|
// get any message coming from federation
|
||||||
// Federation is calling!
|
// Federation is calling!
|
||||||
router.post('/u/:name/inbox', Helpers.verifySignature, async (req, res) => {
|
router.post('/u/:name/inbox', Helpers.verifySignature, async (req, res) => {
|
||||||
|
|
||||||
const b = req.body
|
const b = req.body
|
||||||
|
debug(b.type)
|
||||||
switch (b.type) {
|
switch (b.type) {
|
||||||
case 'Follow':
|
case 'Follow':
|
||||||
Follows.follow(req, res)
|
Follows.follow(req, res)
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ module.exports = {
|
|||||||
inbox: `${config.baseurl}/federation/u/${name}/inbox`,
|
inbox: `${config.baseurl}/federation/u/${name}/inbox`,
|
||||||
outbox: `${config.baseurl}/federation/u/${name}/outbox`,
|
outbox: `${config.baseurl}/federation/u/${name}/outbox`,
|
||||||
followers: `${config.baseurl}/federation/u/${name}/followers`,
|
followers: `${config.baseurl}/federation/u/${name}/followers`,
|
||||||
|
attachment: [{
|
||||||
|
type: 'PropertyValue',
|
||||||
|
name: 'Website',
|
||||||
|
value: `<a href='${config.baseurl}'>${config.baseurl}</a>`
|
||||||
|
}],
|
||||||
|
icon: {
|
||||||
|
type: 'Image',
|
||||||
|
mediaType: 'image/jpeg',
|
||||||
|
url: config.baseurl + '/favicon.ico'
|
||||||
|
},
|
||||||
publicKey: {
|
publicKey: {
|
||||||
id: `${config.baseurl}/federation/u/${name}#main-key`,
|
id: `${config.baseurl}/federation/u/${name}#main-key`,
|
||||||
owner: `${config.baseurl}/federation/u/${name}`,
|
owner: `${config.baseurl}/federation/u/${name}`,
|
||||||
@@ -32,24 +42,35 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
async followers (req, res) {
|
async followers (req, res) {
|
||||||
const name = req.params.name
|
const name = req.params.name
|
||||||
|
const page = req.query.page
|
||||||
|
debug('Retrieve %s followers', name)
|
||||||
if (!name) return res.status(400).send('Bad request.')
|
if (!name) return res.status(400).send('Bad request.')
|
||||||
const user = await User.findOne({where: { username: name }})
|
const user = await User.findOne({where: { username: name }})
|
||||||
if (!user) return res.status(404).send(`No record found for ${name}`)
|
if (!user) return res.status(404).send(`No record found for ${name}`)
|
||||||
const ret = {
|
|
||||||
'@context': [ 'https://www.w3.org/ns/activitystreams' ],
|
res.type('application/activity+json; charset=utf-8')
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
debug('No pagination')
|
||||||
|
return res.json({
|
||||||
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
id: `${config.baseurl}/federation/u/${name}/followers`,
|
id: `${config.baseurl}/federation/u/${name}/followers`,
|
||||||
type: 'OrderedCollection',
|
type: 'OrderedCollection',
|
||||||
totalItems: user.followers.length,
|
totalItems: user.followers.length,
|
||||||
first: {
|
first: `${config.baseurl}/federation/u/${name}/followers?page=true`,
|
||||||
id: `${config.baseurl}/federation/u/${name}/followers?page=1`,
|
last: `${config.baseurl}/federation/u/${name}/followers?page=true`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return res.json({
|
||||||
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
|
id: `${config.baseurl}/federation/u/${name}/followers?page=${page}`,
|
||||||
type: 'OrderedCollectionPage',
|
type: 'OrderedCollectionPage',
|
||||||
totalItems: user.followers.length,
|
totalItems: user.followers.length,
|
||||||
partOf: `${config.baseurl}/federation/u/${name}/followers` ,
|
partOf: `${config.baseurl}/federation/u/${name}/followers` ,
|
||||||
orderedItems: user.followers,
|
orderedItems: user.followers
|
||||||
}
|
})
|
||||||
}
|
|
||||||
res.json(ret)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async outbox (req, res) {
|
async outbox (req, res) {
|
||||||
const name = req.params.name
|
const name = req.params.name
|
||||||
const page = req.query.page
|
const page = req.query.page
|
||||||
@@ -61,33 +82,39 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!user) return res.status(404).send(`No record found for ${name}`)
|
if (!user) return res.status(404).send(`No record found for ${name}`)
|
||||||
|
|
||||||
debug('Inside outbox, should return all events from this user')
|
debug('Inside outbox, should return all events from this user')
|
||||||
|
|
||||||
// https://www.w3.org/TR/activitypub/#outbox
|
// https://www.w3.org/TR/activitypub/#outbox
|
||||||
|
res.type('application/activity+json; charset=utf-8')
|
||||||
if (!page) {
|
if (!page) {
|
||||||
const ret = {
|
debug('Without pagination ')
|
||||||
|
return res.json({
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
id: `${config.baseurl}/federation/u/${name}/outbox`,
|
id: `${config.baseurl}/federation/u/${name}/outbox`,
|
||||||
type: 'OrderedCollection',
|
type: 'OrderedCollection',
|
||||||
totalItems: user.events.length,
|
totalItems: user.events.length,
|
||||||
first: {
|
first: `${config.baseurl}/federation/u/${name}/outbox?page=true`,
|
||||||
id: `${config.baseurl}/federation/u/${name}/outbox?page=true`,
|
last: `${config.baseurl}/federation/u/${name}/outbox?page=true`
|
||||||
type: 'OrderedCollectionPage',
|
})
|
||||||
totalItem: user.events.length,
|
|
||||||
partOf: `${config.baseurl}/federation/u/${name}/outbox`,
|
|
||||||
orderedItems: user.events.map(e => e.toAP(user.username))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
res.type('application/activity+json; charset=utf-8')
|
debug('With pagination %s', page)
|
||||||
return res.json(ret)
|
return res.json({
|
||||||
}
|
|
||||||
const ret = {
|
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
id: `${config.baseurl}/federation/u/${name}/outbox?page=true`,
|
id: `${config.baseurl}/federation/u/${name}/outbox?page=${page}`,
|
||||||
type: 'OrderedCollectionPage',
|
type: 'OrderedCollectionPage',
|
||||||
|
totalItems: user.followers.length,
|
||||||
partOf: `${config.baseurl}/federation/u/${name}/outbox` ,
|
partOf: `${config.baseurl}/federation/u/${name}/outbox` ,
|
||||||
orderedItems: user.events.map(e => e.toAP(user.username))
|
orderedItems: user.events.map(e => ({
|
||||||
}
|
id: `${config.baseurl}/federation/m/${e.id}#create`,
|
||||||
res.type('application/activity+json; charset=utf-8')
|
type: 'Create',
|
||||||
res.json(ret)
|
to: ['https://www.w3.org/ns/activitystreams#Public'],
|
||||||
|
cc: [`${config.baseurl}/federation/u/${user.username}/followers`],
|
||||||
|
published: e.createdAt,
|
||||||
|
actor: `${config.baseurl}/federation/u/${user.username}`,
|
||||||
|
object: e.toAP(user.username)
|
||||||
|
}))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,30 @@ const settingsController = require('../api/controller/settings')
|
|||||||
const config = require('config')
|
const config = require('config')
|
||||||
const version = require('../../package.json').version
|
const version = require('../../package.json').version
|
||||||
const url = require('url')
|
const url = require('url')
|
||||||
|
const debug = require('debug')('webfinger')
|
||||||
|
|
||||||
router.use(cors())
|
router.use(cors())
|
||||||
|
|
||||||
router.get('/webfinger', async (req, res) => {
|
router.get('/webfinger', async (req, res) => {
|
||||||
const resource = req.query.resource
|
const resource = req.query.resource
|
||||||
if (!resource || !resource.includes('acct:')) {
|
if (!resource || !resource.includes('acct:')) {
|
||||||
|
debug('Bad webfinger request => %s', resource.query)
|
||||||
return res.status(400).send('Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.')
|
return res.status(400).send('Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.')
|
||||||
}
|
}
|
||||||
const name = resource.match(/acct:(.*)@/)[1]
|
|
||||||
const domain = url.parse(config.baseurl).host
|
const domain = url.parse(config.baseurl).host
|
||||||
|
const [, name, req_domain] = resource.match(/acct:(.*)@(.*)/)
|
||||||
|
|
||||||
|
if (domain !== req_domain) {
|
||||||
|
debug('Bad webfinger request, requested domain "%s" instead of "%s"', req_domain, domain)
|
||||||
|
return res.status(400).send('Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.')
|
||||||
|
}
|
||||||
|
|
||||||
const user = await User.findOne({ where: { username: name } })
|
const user = await User.findOne({ where: { username: name } })
|
||||||
if (!user) return res.status(404).send(`No record found for ${name}`)
|
if (!user) {
|
||||||
|
debug('User not found: %s', name)
|
||||||
|
return res.status(404).send(`No record found for ${name}`)
|
||||||
|
}
|
||||||
|
|
||||||
const ret = {
|
const ret = {
|
||||||
subject: `acct:${name}@${domain}`,
|
subject: `acct:${name}@${domain}`,
|
||||||
links: [
|
links: [
|
||||||
@@ -40,7 +52,7 @@ router.get('/nodeinfo/:nodeinfo_version', async (req, res) => {
|
|||||||
},
|
},
|
||||||
openRegistrations: settingsController.settings.allow_registration,
|
openRegistrations: settingsController.settings.allow_registration,
|
||||||
protocols: ['activitypub'],
|
protocols: ['activitypub'],
|
||||||
services: { inbound: [], outbound :["atom1.0"]},
|
services: { inbound: [], outbound: ['atom1.0'] },
|
||||||
software: {
|
software: {
|
||||||
name: 'gancio',
|
name: 'gancio',
|
||||||
version
|
version
|
||||||
@@ -83,18 +95,16 @@ router.get('/x-nodeinfo2', async (req, res) => {
|
|||||||
res.json(ret)
|
res.json(ret)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
router.get('/nodeinfo', async (req, res) => {
|
router.get('/nodeinfo', async (req, res) => {
|
||||||
const ret = {
|
const ret = {
|
||||||
links: [
|
links: [
|
||||||
{ href: `${config.baseurl}/.well-known/nodeinfo/2.0`, rel: `http://nodeinfo.diaspora.software/ns/schema/2.0` },
|
{ href: `${config.baseurl}/.well-known/nodeinfo/2.0`, rel: `http://nodeinfo.diaspora.software/ns/schema/2.0` },
|
||||||
{ href: `${config.baseurl}/.well-known/nodeinfo/2.1`, rel: `http://nodeinfo.diaspora.software/ns/schema/2.1` },
|
{ href: `${config.baseurl}/.well-known/nodeinfo/2.1`, rel: `http://nodeinfo.diaspora.software/ns/schema/2.1` }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
res.json(ret)
|
res.json(ret)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
router.use('/host-meta', (req, res) => {
|
router.use('/host-meta', (req, res) => {
|
||||||
res.type('application/xml')
|
res.type('application/xml')
|
||||||
res.send(`<?xml version="1.0" encoding="UTF-8"?>
|
res.send(`<?xml version="1.0" encoding="UTF-8"?>
|
||||||
@@ -104,12 +114,14 @@ router.use('/host-meta', (req, res) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Handle 404
|
// Handle 404
|
||||||
router.use(function(req, res) {
|
router.use((req, res) => {
|
||||||
|
debug('404 Page not found: %s', req.path)
|
||||||
res.status(404).send('404: Page not Found')
|
res.status(404).send('404: Page not Found')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handle 500
|
// Handle 500
|
||||||
router.use(function(error, req, res, next) {
|
router.use((error, req, res, next) => {
|
||||||
|
debug(error)
|
||||||
res.status(500).send('500: Internal Server Error')
|
res.status(500).send('500: Internal Server Error')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -26,4 +26,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -23,4 +23,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -23,4 +23,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -23,4 +23,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -24,4 +24,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -25,4 +25,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: (queryInterface, Sequelize) => {
|
up: (queryInterface, Sequelize) => {
|
||||||
@@ -24,4 +24,4 @@ module.exports = {
|
|||||||
return queryInterface.dropTable('users');
|
return queryInterface.dropTable('users');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const notifier = {
|
|||||||
const eventNotifications = await EventNotification.findAll({ where: { status: 'new' } })
|
const eventNotifications = await EventNotification.findAll({ where: { status: 'new' } })
|
||||||
const promises = eventNotifications.map(async e => {
|
const promises = eventNotifications.map(async e => {
|
||||||
const event = await Event.findByPk(e.eventId, { include: [User, Place, Tag] })
|
const event = await Event.findByPk(e.eventId, { include: [User, Place, Tag] })
|
||||||
if (!event.place) return
|
if (!event.place) { return }
|
||||||
const notification = await Notification.findByPk(e.notificationId)
|
const notification = await Notification.findByPk(e.notificationId)
|
||||||
try {
|
try {
|
||||||
await sendNotification(notification, event, e)
|
await sendNotification(notification, event, e)
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ const webfinger = require('./federation/webfinger')
|
|||||||
const debug = require('debug')('routes')
|
const debug = require('debug')('routes')
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
router.use((req, res, next) => {
|
||||||
|
debug(req.path)
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
|
||||||
router.use('/favicon.ico', express.static(path.resolve(config.favicon || 'assets/favicon.ico')))
|
router.use('/favicon.ico', express.static(path.resolve(config.favicon || 'assets/favicon.ico')))
|
||||||
router.use('/media/', express.static(config.upload_path))
|
router.use('/media/', express.static(config.upload_path))
|
||||||
router.use('/api', api)
|
router.use('/api', api)
|
||||||
@@ -27,6 +32,4 @@ router.use((error, req, res, next) => {
|
|||||||
res.status(500).send('500: Internal Server Error')
|
res.status(500).send('500: Internal Server Error')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const state = () => ({
|
|||||||
allow_anon_event: true,
|
allow_anon_event: true,
|
||||||
allow_recurrent_event: true,
|
allow_recurrent_event: true,
|
||||||
recurrent_event_visible: false,
|
recurrent_event_visible: false,
|
||||||
enable_federation: false,
|
enable_federation: false
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
tags: [],
|
tags: [],
|
||||||
@@ -27,28 +27,26 @@ export const getters = {
|
|||||||
|
|
||||||
// filter matches search tag/place
|
// filter matches search tag/place
|
||||||
filteredEvents: state => {
|
filteredEvents: state => {
|
||||||
|
|
||||||
const search_for_tags = !!state.filters.tags.length
|
const search_for_tags = !!state.filters.tags.length
|
||||||
const search_for_places = !!state.filters.places.length
|
const search_for_places = !!state.filters.places.length
|
||||||
|
|
||||||
return state.events.filter(e => {
|
return state.events.filter(e => {
|
||||||
|
|
||||||
// filter past events
|
// filter past events
|
||||||
if (!state.filters.show_past_events && e.past) return false
|
if (!state.filters.show_past_events && e.past) { return false }
|
||||||
|
|
||||||
// filter recurrent events
|
// filter recurrent events
|
||||||
if (!state.filters.show_recurrent_events && e.recurrent) return false
|
if (!state.filters.show_recurrent_events && e.recurrent) { return false }
|
||||||
|
|
||||||
if (search_for_places) {
|
if (search_for_places) {
|
||||||
if (find(state.filters.places, p => p === e.place.id)) return true
|
if (find(state.filters.places, p => p === e.place.id)) { return true }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_for_tags) {
|
if (search_for_tags) {
|
||||||
const common_tags = intersection(e.tags, state.filters.tags);
|
const common_tags = intersection(e.tags, state.filters.tags)
|
||||||
if (common_tags.length > 0) return true
|
if (common_tags.length > 0) { return true }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!search_for_places && !search_for_tags) return true
|
if (!search_for_places && !search_for_tags) { return true }
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
@@ -56,7 +54,6 @@ export const getters = {
|
|||||||
|
|
||||||
// filter matches search tag/place including past events
|
// filter matches search tag/place including past events
|
||||||
filteredEventsWithPast: state => {
|
filteredEventsWithPast: state => {
|
||||||
|
|
||||||
const search_for_tags = !!state.filters.tags.length
|
const search_for_tags = !!state.filters.tags.length
|
||||||
const search_for_places = !!state.filters.places.length
|
const search_for_places = !!state.filters.places.length
|
||||||
|
|
||||||
@@ -64,18 +61,18 @@ export const getters = {
|
|||||||
const match = false
|
const match = false
|
||||||
|
|
||||||
// filter recurrent events
|
// filter recurrent events
|
||||||
if (!state.filters.show_recurrent_events && e.recurrent) return false
|
if (!state.filters.show_recurrent_events && e.recurrent) { return false }
|
||||||
|
|
||||||
if (!match && search_for_places) {
|
if (!match && search_for_places) {
|
||||||
if (find(state.filters.places, p => p === e.place.id)) return true
|
if (find(state.filters.places, p => p === e.place.id)) { return true }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_for_tags) {
|
if (search_for_tags) {
|
||||||
const common_tags = intersection(e.tags, state.filters.tags);
|
const common_tags = intersection(e.tags, state.filters.tags)
|
||||||
if (common_tags.length > 0) return true
|
if (common_tags.length > 0) { return true }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!search_for_places && !search_for_tags) return true
|
if (!search_for_places && !search_for_tags) { return true }
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
@@ -101,7 +98,7 @@ export const mutations = {
|
|||||||
},
|
},
|
||||||
updateEvent (state, event) {
|
updateEvent (state, event) {
|
||||||
state.events = state.events.map((e) => {
|
state.events = state.events.map((e) => {
|
||||||
if (e.id !== event.id) return e
|
if (e.id !== event.id) { return e }
|
||||||
return event
|
return event
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -146,7 +143,6 @@ export const actions = {
|
|||||||
|
|
||||||
// apply settings
|
// apply settings
|
||||||
commit('showRecurrentEvents', settings.allow_recurrent_event && settings.recurrent_event_visible)
|
commit('showRecurrentEvents', settings.allow_recurrent_event && settings.recurrent_event_visible)
|
||||||
|
|
||||||
},
|
},
|
||||||
async updateEvents ({ commit }, page) {
|
async updateEvents ({ commit }, page) {
|
||||||
const events = await this.$axios.$get(`/event/${page.month - 1}/${page.year}`)
|
const events = await this.$axios.$get(`/event/${page.month - 1}/${page.year}`)
|
||||||
@@ -186,5 +182,5 @@ export const actions = {
|
|||||||
async setSetting ({ commit }, setting) {
|
async setSetting ({ commit }, setting) {
|
||||||
await this.$axios.$post('/settings', setting)
|
await this.$axios.$post('/settings', setting)
|
||||||
commit('setSetting', setting)
|
commit('setSetting', setting)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4162,6 +4162,11 @@ express-jwt@^5.3.1:
|
|||||||
jsonwebtoken "^8.1.0"
|
jsonwebtoken "^8.1.0"
|
||||||
lodash.set "^4.0.0"
|
lodash.set "^4.0.0"
|
||||||
|
|
||||||
|
express-middleware-log@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/express-middleware-log/-/express-middleware-log-1.2.0.tgz#62682021ba3b1cbfd6b081e7364ebb1fd6d5a0fb"
|
||||||
|
integrity sha512-1G9cHlGJs4+nFphSqVduJfCzeaqHeOdpTRBAjceRRcLWeHzj9sXDYP99tNjaeHsHn3N3vlNI+vIn/lb9eYXmuw==
|
||||||
|
|
||||||
express-unless@^0.3.0:
|
express-unless@^0.3.0:
|
||||||
version "0.3.1"
|
version "0.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/express-unless/-/express-unless-0.3.1.tgz#2557c146e75beb903e2d247f9b5ba01452696e20"
|
resolved "https://registry.yarnpkg.com/express-unless/-/express-unless-0.3.1.tgz#2557c146e75beb903e2d247f9b5ba01452696e20"
|
||||||
|
|||||||
Reference in New Issue
Block a user