mirror of
https://framagit.org/les/gancio.git
synced 2025-01-31 16:42:22 +01:00
toggle plugins / save dynamic plugin settings
This commit is contained in:
parent
982db2b51d
commit
246f1dfb20
7 changed files with 433 additions and 377 deletions
|
@ -10,7 +10,10 @@ v-container
|
||||||
v-card-text
|
v-card-text
|
||||||
v-form(v-model='valid' ref='form' lazy-validation)
|
v-form(v-model='valid' ref='form' lazy-validation)
|
||||||
div(v-for='(setting, name) in selectedPlugin.settings')
|
div(v-for='(setting, name) in selectedPlugin.settings')
|
||||||
v-text-field(v-model='pluginSettings[name]' type='text' :label='setting.description')
|
v-text-field(v-if='setting.type === "TEXT"' v-model='selectedPlugin.settingsValue[name]' type='text' :label='setting.description')
|
||||||
|
v-text-field(v-if='setting.type === "NUMBER"' v-model='selectedPlugin.settingsValue[name]' type='number' :label='setting.description')
|
||||||
|
v-switch(v-if='setting.type === "CHECK"' v-model='selectedPlugin.settingsValue[name]' :label='setting.description')
|
||||||
|
v-select(v-if='setting.type === "LIST"' v-model='selectedPlugin.settingsValue[name]' :items='setting.items' :label='setting.description')
|
||||||
|
|
||||||
v-card-actions
|
v-card-actions
|
||||||
v-spacer
|
v-spacer
|
||||||
|
@ -19,9 +22,9 @@ v-container
|
||||||
:disable='!valid || loading') {{ $t('common.save') }}
|
:disable='!valid || loading') {{ $t('common.save') }}
|
||||||
|
|
||||||
v-card-text
|
v-card-text
|
||||||
v-card(v-for='plugin in plugins' :key='plugin.name' max-width="400" elevation='10' color='secondary')
|
v-card(v-for='plugin in plugins' :key='plugin.name' max-width="400" elevation='10' color='secondary' dark)
|
||||||
v-card-title.d-block {{ plugin.name }}
|
v-card-title.d-block {{ plugin.name }}
|
||||||
v-switch.float-right(:label="$t('common.enable')" @change='toggleEnable(plugin)')
|
v-switch.float-right(:label="$t('common.enable')" v-model='plugin.settingsValue.enable' @change='toggleEnable(plugin)')
|
||||||
v-card-text
|
v-card-text
|
||||||
p {{ plugin.description }}
|
p {{ plugin.description }}
|
||||||
blockquote author: {{ plugin.author }}
|
blockquote author: {{ plugin.author }}
|
||||||
|
@ -33,6 +36,7 @@ v-container
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mdiPencil, mdiChevronLeft, mdiChevronRight, mdiMagnify, mdiEye } from '@mdi/js'
|
import { mdiPencil, mdiChevronLeft, mdiChevronRight, mdiMagnify, mdiEye } from '@mdi/js'
|
||||||
|
import { mapActions, mapState } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
@ -42,7 +46,6 @@ export default {
|
||||||
dialog: false,
|
dialog: false,
|
||||||
valid: false,
|
valid: false,
|
||||||
selectedPlugin: {},
|
selectedPlugin: {},
|
||||||
pluginSettings: {},
|
|
||||||
plugins: [],
|
plugins: [],
|
||||||
headers: [
|
headers: [
|
||||||
{ value: 'name', text: 'Name' },
|
{ value: 'name', text: 'Name' },
|
||||||
|
@ -51,22 +54,26 @@ export default {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async fetch() {
|
async mounted() {
|
||||||
this.plugins = await this.$axios.$get('/plugins')
|
this.plugins = await this.$axios.$get('/plugins')
|
||||||
},
|
},
|
||||||
|
computed: mapState(['settings']),
|
||||||
methods: {
|
methods: {
|
||||||
saveSettings() {
|
...mapActions(['setSetting']),
|
||||||
console.error(this.pluginSettings)
|
async saveSettings() {
|
||||||
this.setSetting({ key: 'plugin_' + this.selectedPlugin.name, value: this.pluginSettings })
|
this.loading = true
|
||||||
|
this.setSetting({
|
||||||
|
key: 'plugin_' + this.selectedPlugin.name,
|
||||||
|
value: this.selectedPlugin.settingsValue
|
||||||
|
})
|
||||||
|
this.loading = false
|
||||||
|
this.dialog = false
|
||||||
},
|
},
|
||||||
toggleEnable(plugin) {
|
async toggleEnable(plugin) {
|
||||||
this.pluginSettings.enable = !this.pluginSettings.enable
|
await this.$axios.$put(`/plugin/${plugin.name}`)
|
||||||
this.setSetting({ key: 'plugin_' + this.selectedPlugin.name, value: this.pluginSettings })
|
|
||||||
},
|
},
|
||||||
setOptions(plugin) {
|
setOptions(plugin) {
|
||||||
console.error(plugin)
|
|
||||||
this.selectedPlugin = plugin
|
this.selectedPlugin = plugin
|
||||||
console.error(plugin)
|
|
||||||
this.dialog = true
|
this.dialog = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
587
locales/en.json
587
locales/en.json
|
@ -1,295 +1,298 @@
|
||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
"add_event": "Add event",
|
"add_event": "Add event",
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"export": "Export",
|
"export": "Export",
|
||||||
"send": "Send",
|
"send": "Send",
|
||||||
"where": "Where",
|
"where": "Where",
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"when": "When",
|
"when": "When",
|
||||||
"what": "What",
|
"what": "What",
|
||||||
"media": "Media",
|
"media": "Media",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"email": "E-mail",
|
"email": "E-mail",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"register": "Register",
|
"register": "Register",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
"hide": "Hide",
|
"hide": "Hide",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"admin": "Admin",
|
"admin": "Admin",
|
||||||
"users": "Users",
|
"users": "Users",
|
||||||
"events": "Events",
|
"events": "Events",
|
||||||
"places": "Places",
|
"places": "Places",
|
||||||
"settings": "Options",
|
"settings": "Options",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"deactivate": "Turn off",
|
"deactivate": "Turn off",
|
||||||
"remove_admin": "Remove admin",
|
"remove_admin": "Remove admin",
|
||||||
"activate": "Activate",
|
"activate": "Activate",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"logout": "Log out",
|
"logout": "Log out",
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"associate": "Associate",
|
"associate": "Associate",
|
||||||
"edit_event": "Edit event",
|
"edit_event": "Edit event",
|
||||||
"related": "Related",
|
"related": "Related",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"logout_ok": "Logged out",
|
"logout_ok": "Logged out",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
"recover_password": "Recover password",
|
"recover_password": "Recover password",
|
||||||
"new_password": "New password",
|
"new_password": "New password",
|
||||||
"new_user": "New user",
|
"new_user": "New user",
|
||||||
"ok": "Ok",
|
"ok": "Ok",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"disable": "Disable",
|
"disable": "Disable",
|
||||||
"me": "You",
|
"me": "You",
|
||||||
"password_updated": "Password changed.",
|
"password_updated": "Password changed.",
|
||||||
"resources": "Resources",
|
"resources": "Resources",
|
||||||
"n_resources": "no resource|a resource|{n} resources",
|
"n_resources": "no resource|a resource|{n} resources",
|
||||||
"activate_user": "Confirmed",
|
"activate_user": "Confirmed",
|
||||||
"displayname": "Display name",
|
"displayname": "Display name",
|
||||||
"federation": "Federation",
|
"federation": "Federation",
|
||||||
"set_password": "Set password",
|
"set_password": "Set password",
|
||||||
"copy_link": "Copy link",
|
"copy_link": "Copy link",
|
||||||
"send_via_mail": "Send e-mail",
|
"send_via_mail": "Send e-mail",
|
||||||
"add_to_calendar": "Add to calendar",
|
"add_to_calendar": "Add to calendar",
|
||||||
"instances": "Instances",
|
"instances": "Instances",
|
||||||
"copied": "Copied",
|
"copied": "Copied",
|
||||||
"embed": "Embed",
|
"embed": "Embed",
|
||||||
"embed_title": "Embed this event on your website",
|
"embed_title": "Embed this event on your website",
|
||||||
"embed_help": "Copying the following code into your website and the event will be shown like here",
|
"embed_help": "Copying the following code into your website and the event will be shown like here",
|
||||||
"feed": "RSS Feed",
|
"feed": "RSS Feed",
|
||||||
"feed_url_copied": "Open the copied feed URL in your RSS feed reader",
|
"feed_url_copied": "Open the copied feed URL in your RSS feed reader",
|
||||||
"follow_me_title": "Follow updates from fediverse",
|
"follow_me_title": "Follow updates from fediverse",
|
||||||
"follow": "Follow",
|
"follow": "Follow",
|
||||||
"moderation": "Moderation",
|
"moderation": "Moderation",
|
||||||
"user": "User",
|
"user": "User",
|
||||||
"authorize": "Authorize",
|
"authorize": "Authorize",
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"filter": "Filter",
|
"filter": "Filter",
|
||||||
"event": "Event",
|
"event": "Event",
|
||||||
"pause": "Pause",
|
"pause": "Pause",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"fediverse": "Fediverse",
|
"fediverse": "Fediverse",
|
||||||
"skip": "Skip",
|
"skip": "Skip",
|
||||||
"delete": "Remove",
|
"delete": "Remove",
|
||||||
"announcements": "Announcements",
|
"announcements": "Announcements",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"place": "Place",
|
"place": "Place",
|
||||||
"tags": "Tags",
|
"tags": "Tags",
|
||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
"import": "Import",
|
"import": "Import",
|
||||||
"max_events": "N. max events",
|
"max_events": "N. max events",
|
||||||
"label": "Label",
|
"label": "Label",
|
||||||
"collections": "Collections",
|
"collections": "Collections",
|
||||||
"close": "Close"
|
"close": "Close",
|
||||||
},
|
"plugins": "Plugins"
|
||||||
"login": {
|
},
|
||||||
"description": "By logging in you can publish new events.",
|
"login": {
|
||||||
"check_email": "Check your e-mail inbox and spam.",
|
"description": "By logging in you can publish new events.",
|
||||||
"not_registered": "Not registered?",
|
"check_email": "Check your e-mail inbox and spam.",
|
||||||
"forgot_password": "Forgot your password?",
|
"not_registered": "Not registered?",
|
||||||
"error": "Could not log in. Check your login info.",
|
"forgot_password": "Forgot your password?",
|
||||||
"insert_email": "Enter your e-mail address",
|
"error": "Could not log in. Check your login info.",
|
||||||
"ok": "Logged in"
|
"insert_email": "Enter your e-mail address",
|
||||||
},
|
"ok": "Logged in"
|
||||||
"recover": {
|
},
|
||||||
"not_valid_code": "Something went wrong."
|
"recover": {
|
||||||
},
|
"not_valid_code": "Something went wrong."
|
||||||
"export": {
|
},
|
||||||
"intro": "Unlike the unsocial platforms that do everything to keep users and data about them, we believe that information, like people, must be free. For this you can stay updated on the events you want, without necessarily going through this site.",
|
"export": {
|
||||||
"email_description": "You can get events that interest sent via e-mail.",
|
"intro": "Unlike the unsocial platforms that do everything to keep users and data about them, we believe that information, like people, must be free. For this you can stay updated on the events you want, without necessarily going through this site.",
|
||||||
"insert_your_address": "Enter your e-mail address",
|
"email_description": "You can get events that interest sent via e-mail.",
|
||||||
"feed_description": "To follow updates from a computer or smartphone without the need to periodically open this site, use RSS feeds. </p>\n\n<p> With RSS feeds you use a special app to receive updates from sites that interest you. It's a good way to follow many sites quickly, without the need to create an account or other complications. </p>\n\n<li> If you have Android, we recommend <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> or Feeder </li>\n<li> For iPhone / iPad you can use <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> For desktop / laptop we recommend Feedbro, to be installed on <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> or <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdding this link to your RSS feed reader will keep you up to date.",
|
"insert_your_address": "Enter your e-mail address",
|
||||||
"ical_description": "Computers and smartphones are commonly equipped with a calendar app capable of importing a remote calendar.",
|
"feed_description": "To follow updates from a computer or smartphone without the need to periodically open this site, use RSS feeds. </p>\n\n<p> With RSS feeds you use a special app to receive updates from sites that interest you. It's a good way to follow many sites quickly, without the need to create an account or other complications. </p>\n\n<li> If you have Android, we recommend <a href=\"https://f-droid.org/en/packages/net.frju.flym/\">Flym</a> or Feeder </li>\n<li> For iPhone / iPad you can use <a href=\"https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8\"> Feed4U </a> </li>\n<li> For desktop / laptop we recommend Feedbro, to be installed on <a href=\"https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/\"> Firefox </a> or <a href=\"https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa\"> Chrome </a>. </li>\n<br/>\nAdding this link to your RSS feed reader will keep you up to date.",
|
||||||
"list_description": "If you have a website and want to show a list of events, use the following code"
|
"ical_description": "Computers and smartphones are commonly equipped with a calendar app capable of importing a remote calendar.",
|
||||||
},
|
"list_description": "If you have a website and want to show a list of events, use the following code"
|
||||||
"register": {
|
},
|
||||||
"description": "Social movements should organize and self-finance.<br/>\n<br/>Before you can publish, <strong> the account must be approved</strong>, consider that <strong> behind this site you will find real people</strong>, so write two lines to let us know what events you would like to publish.",
|
"register": {
|
||||||
"error": "Error: ",
|
"description": "Social movements should organize and self-finance.<br/>\n<br/>Before you can publish, <strong> the account must be approved</strong>, consider that <strong> behind this site you will find real people</strong>, so write two lines to let us know what events you would like to publish.",
|
||||||
"complete": "Registration has to be confirmed.",
|
"error": "Error: ",
|
||||||
"first_user": "Administrator created"
|
"complete": "Registration has to be confirmed.",
|
||||||
},
|
"first_user": "Administrator created"
|
||||||
"event": {
|
},
|
||||||
"anon": "Anon",
|
"event": {
|
||||||
"anon_description": "You can add an event without registering or logging in, but will have to wait for someone to read it,\nconfirming that it is a suitable event. It will not be possible to modify it.<br/><br/>\nYou can instead <a href='/login'>log in</a> or <a href='/register'>register</a>. Otherwise go ahead and get an answer as soon as possible. ",
|
"anon": "Anon",
|
||||||
"same_day": "on same day",
|
"anon_description": "You can add an event without registering or logging in, but will have to wait for someone to read it,\nconfirming that it is a suitable event. It will not be possible to modify it.<br/><br/>\nYou can instead <a href='/login'>log in</a> or <a href='/register'>register</a>. Otherwise go ahead and get an answer as soon as possible. ",
|
||||||
"what_description": "Title",
|
"same_day": "on same day",
|
||||||
"description_description": "Description",
|
"what_description": "Title",
|
||||||
"tag_description": "Tag",
|
"description_description": "Description",
|
||||||
"media_description": "You can add a flyer (optional)",
|
"tag_description": "Tag",
|
||||||
"added": "Event added",
|
"media_description": "You can add a flyer (optional)",
|
||||||
"saved": "Event saved",
|
"added": "Event added",
|
||||||
"added_anon": "Event added, but has yet to be confirmed.",
|
"saved": "Event saved",
|
||||||
"updated": "Event updated",
|
"added_anon": "Event added, but has yet to be confirmed.",
|
||||||
"where_description": "Where's the event? If not present you can create it.",
|
"updated": "Event updated",
|
||||||
"confirmed": "Event confirmed",
|
"where_description": "Where's the event? If not present you can create it.",
|
||||||
"not_found": "Could not find event",
|
"confirmed": "Event confirmed",
|
||||||
"remove_confirmation": "Are you sure you want to remove this event?",
|
"not_found": "Could not find event",
|
||||||
"recurrent": "Recurring",
|
"remove_confirmation": "Are you sure you want to remove this event?",
|
||||||
"edit_recurrent": "Edit recurring event:",
|
"recurrent": "Recurring",
|
||||||
"show_recurrent": "recurring events",
|
"edit_recurrent": "Edit recurring event:",
|
||||||
"show_past": "also prior events",
|
"show_recurrent": "recurring events",
|
||||||
"only_future": "only upcoming events",
|
"show_past": "also prior events",
|
||||||
"recurrent_description": "Choose frequency and select days",
|
"only_future": "only upcoming events",
|
||||||
"multidate_description": "Is it a festival? Choose when it starts and ends",
|
"recurrent_description": "Choose frequency and select days",
|
||||||
"multidate": "More days",
|
"multidate_description": "Is it a festival? Choose when it starts and ends",
|
||||||
"normal": "Normal",
|
"multidate": "More days",
|
||||||
"normal_description": "Choose the day.",
|
"normal": "Normal",
|
||||||
"recurrent_1w_days": "Each {days}",
|
"normal_description": "Choose the day.",
|
||||||
"recurrent_2w_days": "A {days} every other",
|
"recurrent_1w_days": "Each {days}",
|
||||||
"recurrent_1m_days": "|The {days} of each month|{days} of each month",
|
"recurrent_2w_days": "A {days} every other",
|
||||||
"recurrent_2m_days": "|The {days} a month every other|The {days} a month every other",
|
"recurrent_1m_days": "|The {days} of each month|{days} of each month",
|
||||||
"recurrent_1m_ordinal": "The {n} {days} of each month",
|
"recurrent_2m_days": "|The {days} a month every other|The {days} a month every other",
|
||||||
"recurrent_2m_ordinal": "|The {n} {days} a month every other|The {n} {days} a month every other",
|
"recurrent_1m_ordinal": "The {n} {days} of each month",
|
||||||
"each_week": "Each week",
|
"recurrent_2m_ordinal": "|The {n} {days} a month every other|The {n} {days} a month every other",
|
||||||
"each_2w": "Every other weeks",
|
"each_week": "Each week",
|
||||||
"each_month": "Each month",
|
"each_2w": "Every other weeks",
|
||||||
"due": "until",
|
"each_month": "Each month",
|
||||||
"from": "From",
|
"due": "until",
|
||||||
"image_too_big": "The image can't be bigger than 4MB",
|
"from": "From",
|
||||||
"interact_with_me_at": "Interact with me on fediverse at",
|
"image_too_big": "The image can't be bigger than 4MB",
|
||||||
"follow_me_description": "One of the ways to stay up to date on events published here on {title},\nis following the account <u>{account}</u> from the fediverse, for example via Mastodon, and possibly add resources to an event from there.<br/><br/>\nIf you have never heard of Mastodon and the fediverse we recommend reading <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>this article</a>.<br/><br/>Enter your instance below (e.g. mastodon.social)",
|
"interact_with_me_at": "Interact with me on fediverse at",
|
||||||
"interact_with_me": "Follow me",
|
"follow_me_description": "One of the ways to stay up to date on events published here on {title},\nis following the account <u>{account}</u> from the fediverse, for example via Mastodon, and possibly add resources to an event from there.<br/><br/>\nIf you have never heard of Mastodon and the fediverse we recommend reading <a href='https://www.savjee.be/videos/simply-explained/mastodon-and-fediverse-explained/'>this article</a>.<br/><br/>Enter your instance below (e.g. mastodon.social)",
|
||||||
"remove_recurrent_confirmation": "Are you sure you want to remove this recurring event?\nPast events will be maintained, but no further events will be created.",
|
"interact_with_me": "Follow me",
|
||||||
"import_URL": "Import from URL",
|
"remove_recurrent_confirmation": "Are you sure you want to remove this recurring event?\nPast events will be maintained, but no further events will be created.",
|
||||||
"import_ICS": "Import from ICS",
|
"import_URL": "Import from URL",
|
||||||
"ics": "ICS",
|
"import_ICS": "Import from ICS",
|
||||||
"import_description": "You can import events from other platforms and other instances through standard formats (ics and h-event)",
|
"ics": "ICS",
|
||||||
"alt_text_description": "Description for people with visual impairments",
|
"import_description": "You can import events from other platforms and other instances through standard formats (ics and h-event)",
|
||||||
"choose_focal_point": "Choose the focal point",
|
"alt_text_description": "Description for people with visual impairments",
|
||||||
"remove_media_confirmation": "Do you confirm the image removal?",
|
"choose_focal_point": "Choose the focal point",
|
||||||
"download_flyer": "Download flyer"
|
"remove_media_confirmation": "Do you confirm the image removal?",
|
||||||
},
|
"download_flyer": "Download flyer"
|
||||||
"admin": {
|
},
|
||||||
"place_description": "If you have gotten the place or address wrong, you can change it.<br/>All current and past events associated with this place will change address.",
|
"admin": {
|
||||||
"event_confirm_description": "You can confirm events entered by anonymous users here",
|
"place_description": "If you have gotten the place or address wrong, you can change it.<br/>All current and past events associated with this place will change address.",
|
||||||
"delete_user": "Remove",
|
"event_confirm_description": "You can confirm events entered by anonymous users here",
|
||||||
"remove_admin": "Remove admin",
|
"delete_user": "Remove",
|
||||||
"disable_user_confirm": "Are you sure you want to disable {user}?",
|
"remove_admin": "Remove admin",
|
||||||
"delete_user_confirm": "Are you sure you want to remove {user}?",
|
"disable_user_confirm": "Are you sure you want to disable {user}?",
|
||||||
"disable_admin_user_confirm": "Are you sure to remove admin permissions from {user}?",
|
"delete_user_confirm": "Are you sure you want to remove {user}?",
|
||||||
"enable_admin_user_confirm": "Are sure to add admin permissions to {user}",
|
"disable_admin_user_confirm": "Are you sure to remove admin permissions from {user}?",
|
||||||
"user_remove_ok": "User removed",
|
"enable_admin_user_confirm": "Are sure to add admin permissions to {user}",
|
||||||
"user_create_ok": "User created",
|
"user_remove_ok": "User removed",
|
||||||
"event_remove_ok": "Event removed",
|
"user_create_ok": "User created",
|
||||||
"allow_registration_description": "Allow open registrations?",
|
"event_remove_ok": "Event removed",
|
||||||
"allow_anon_event": "Allow anonymous events (has to be confirmed)?",
|
"allow_registration_description": "Allow open registrations?",
|
||||||
"allow_recurrent_event": "Allow recurring events",
|
"allow_anon_event": "Allow anonymous events (has to be confirmed)?",
|
||||||
"recurrent_event_visible": "Show recurring events by default",
|
"allow_recurrent_event": "Allow recurring events",
|
||||||
"federation": "Federation / ActivityPub",
|
"recurrent_event_visible": "Show recurring events by default",
|
||||||
"enable_federation": "Turn on federation",
|
"federation": "Federation / ActivityPub",
|
||||||
"enable_federation_help": "It will be possible to follow this instance from the fediverse",
|
"enable_federation": "Turn on federation",
|
||||||
"add_instance": "Add instance",
|
"enable_federation_help": "It will be possible to follow this instance from the fediverse",
|
||||||
"select_instance_timezone": "Time zone",
|
"add_instance": "Add instance",
|
||||||
"enable_resources": "Turn on resources",
|
"select_instance_timezone": "Time zone",
|
||||||
"enable_resources_help": "Allows adding resources to the event from the fediverse",
|
"enable_resources": "Turn on resources",
|
||||||
"hide_boost_bookmark": "Hides boost/bookmarks",
|
"enable_resources_help": "Allows adding resources to the event from the fediverse",
|
||||||
"hide_boost_bookmark_help": "Hides the small icons showing the number of boosts and bookmarks coming from the fediverse",
|
"hide_boost_bookmark": "Hides boost/bookmarks",
|
||||||
"block": "Block",
|
"hide_boost_bookmark_help": "Hides the small icons showing the number of boosts and bookmarks coming from the fediverse",
|
||||||
"unblock": "Unblock",
|
"block": "Block",
|
||||||
"user_add_help": "An e-mail with instructions on confirming the subscription and choosing a password will be sent to the new user",
|
"unblock": "Unblock",
|
||||||
"instance_name": "Instance name",
|
"user_add_help": "An e-mail with instructions on confirming the subscription and choosing a password will be sent to the new user",
|
||||||
"show_resource": "Show resource",
|
"instance_name": "Instance name",
|
||||||
"hide_resource": "Hide resource",
|
"show_resource": "Show resource",
|
||||||
"delete_resource": "Delete resource",
|
"hide_resource": "Hide resource",
|
||||||
"delete_resource_confirm": "Are you sure you want to delete this resource?",
|
"delete_resource": "Delete resource",
|
||||||
"block_user": "Block user",
|
"delete_resource_confirm": "Are you sure you want to delete this resource?",
|
||||||
"filter_instances": "Filter instances",
|
"block_user": "Block user",
|
||||||
"filter_users": "Filter users",
|
"filter_instances": "Filter instances",
|
||||||
"resources": "Resources",
|
"filter_users": "Filter users",
|
||||||
"user_blocked": "User {user} blocked",
|
"resources": "Resources",
|
||||||
"favicon": "Logo",
|
"user_blocked": "User {user} blocked",
|
||||||
"user_block_confirm": "Are you sure you want to block user {user}?",
|
"favicon": "Logo",
|
||||||
"instance_block_confirm": "Are you sure you want block instance {instance}?",
|
"user_block_confirm": "Are you sure you want to block user {user}?",
|
||||||
"delete_announcement_confirm": "Are you sure you want to remove the announcement?",
|
"instance_block_confirm": "Are you sure you want block instance {instance}?",
|
||||||
"announcement_remove_ok": "Announce removed",
|
"delete_announcement_confirm": "Are you sure you want to remove the announcement?",
|
||||||
"announcement_description": "In this section you can insert announcements to remain on the homepage",
|
"announcement_remove_ok": "Announce removed",
|
||||||
"instance_locale": "Default language",
|
"announcement_description": "In this section you can insert announcements to remain on the homepage",
|
||||||
"instance_timezone_description": "Gancio is designed to collect the events of a specific place, such as a city. All events in this place will be shown in the time zone chosen for it.",
|
"instance_locale": "Default language",
|
||||||
"instance_locale_description": "Preferred user language for pages. Sometimes messages must be shown in the same language for everyone (for example when publishing via ActivityPub or when sending some e-mails). In these cases the language selected above will be used.",
|
"instance_timezone_description": "Gancio is designed to collect the events of a specific place, such as a city. All events in this place will be shown in the time zone chosen for it.",
|
||||||
"title_description": "It is used in the title of the page, in the subject of the e-mail to export RSS and ICS feeds.",
|
"instance_locale_description": "Preferred user language for pages. Sometimes messages must be shown in the same language for everyone (for example when publishing via ActivityPub or when sending some e-mails). In these cases the language selected above will be used.",
|
||||||
"description_description": "Appears in the header next to the title",
|
"title_description": "It is used in the title of the page, in the subject of the e-mail to export RSS and ICS feeds.",
|
||||||
"instance_place": "Indicative place of this instance",
|
"description_description": "Appears in the header next to the title",
|
||||||
"instance_name_help": "ActivityPub's account to follow",
|
"instance_place": "Indicative place of this instance",
|
||||||
"enable_trusted_instances": "Turn on friendly instances",
|
"instance_name_help": "ActivityPub's account to follow",
|
||||||
"trusted_instances_help": "The list of friendly instances will be shown in the header",
|
"enable_trusted_instances": "Turn on friendly instances",
|
||||||
"add_trusted_instance": "Add a friendly instance",
|
"trusted_instances_help": "The list of friendly instances will be shown in the header",
|
||||||
"instance_place_help": "The label to show in instances of others",
|
"add_trusted_instance": "Add a friendly instance",
|
||||||
"delete_trusted_instance_confirm": "Do you really want to delete this item from the friend instance menu?",
|
"instance_place_help": "The label to show in instances of others",
|
||||||
"is_dark": "Dark theme",
|
"delete_trusted_instance_confirm": "Do you really want to delete this item from the friend instance menu?",
|
||||||
"add_link": "Add link",
|
"is_dark": "Dark theme",
|
||||||
"footer_links": "Footer links",
|
"add_link": "Add link",
|
||||||
"delete_footer_link_confirm": "Sure to remove this link?",
|
"footer_links": "Footer links",
|
||||||
"edit_place": "Edit place",
|
"delete_footer_link_confirm": "Sure to remove this link?",
|
||||||
"new_announcement": "New announcement",
|
"edit_place": "Edit place",
|
||||||
"show_smtp_setup": "Email settings",
|
"new_announcement": "New announcement",
|
||||||
"smtp_hostname": "SMTP Hostname",
|
"show_smtp_setup": "Email settings",
|
||||||
"smtp_port": "SMTP Port",
|
"smtp_hostname": "SMTP Hostname",
|
||||||
"smtp_secure": "SMTP Secure (TLS or STARTTLS)",
|
"smtp_port": "SMTP Port",
|
||||||
"smtp_description": "<ul><li>Admin should receive an email when anon event is added (if enabled).</li><li>Admin should receive email of registration request (if enabled).</li><li>User should receive an email of registration request.</li><li>User should receive email of confirmed registration.</li><li>User should receive a confirmation email when subscribed directly by admin.</li><li>Users should receive email to restore password when they forgot it</li></ul>",
|
"smtp_secure": "SMTP Secure (TLS or STARTTLS)",
|
||||||
"smtp_test_success": "A test email is sent to {admin_email}, please check your inbox",
|
"smtp_description": "<ul><li>Admin should receive an email when anon event is added (if enabled).</li><li>Admin should receive email of registration request (if enabled).</li><li>User should receive an email of registration request.</li><li>User should receive email of confirmed registration.</li><li>User should receive a confirmation email when subscribed directly by admin.</li><li>Users should receive email to restore password when they forgot it</li></ul>",
|
||||||
"smtp_test_button": "Send a test email",
|
"smtp_test_success": "A test email is sent to {admin_email}, please check your inbox",
|
||||||
"smtp_use_sendmail": "Use sendmail",
|
"smtp_test_button": "Send a test email",
|
||||||
"sender_email": "Sender e-mail",
|
"smtp_use_sendmail": "Use sendmail",
|
||||||
"widget": "Widget",
|
"sender_email": "Sender e-mail",
|
||||||
"wrong_domain_warning": "The baseurl configured in config.json <b>({baseurl})</b> differs from the one you're visiting <b>({url})</b>",
|
"widget": "Widget",
|
||||||
"new_collection": "New collection",
|
"wrong_domain_warning": "The baseurl configured in config.json <b>({baseurl})</b> differs from the one you're visiting <b>({url})</b>",
|
||||||
"collections_description": "Collections are groupings of events by tags and places. They will be displayed on the home page",
|
"new_collection": "New collection",
|
||||||
"edit_collection": "Edit Collection"
|
"collections_description": "Collections are groupings of events by tags and places. They will be displayed on the home page",
|
||||||
},
|
"edit_collection": "Edit Collection",
|
||||||
"auth": {
|
"config_plugin": "Plugin configuration",
|
||||||
"not_confirmed": "Not confirmed yet…",
|
"plugins_description": ""
|
||||||
"fail": "Could not log in. Are you sure the password is correct?"
|
},
|
||||||
},
|
"auth": {
|
||||||
"settings": {
|
"not_confirmed": "Not confirmed yet…",
|
||||||
"update_confirm": "Do you want to save your modification?",
|
"fail": "Could not log in. Are you sure the password is correct?"
|
||||||
"change_password": "Change your password",
|
},
|
||||||
"password_updated": "Password changed.",
|
"settings": {
|
||||||
"danger_section": "Dangerous section",
|
"update_confirm": "Do you want to save your modification?",
|
||||||
"remove_account": "By pressing the following button your user account will be deleted. Events you published won't be.",
|
"change_password": "Change your password",
|
||||||
"remove_account_confirm": "You are about to permanently delete your account"
|
"password_updated": "Password changed.",
|
||||||
},
|
"danger_section": "Dangerous section",
|
||||||
"error": {
|
"remove_account": "By pressing the following button your user account will be deleted. Events you published won't be.",
|
||||||
"nick_taken": "This nickname is already in use.",
|
"remove_account_confirm": "You are about to permanently delete your account"
|
||||||
"email_taken": "This e-mail is already in use."
|
},
|
||||||
},
|
"error": {
|
||||||
"confirm": {
|
"nick_taken": "This nickname is already in use.",
|
||||||
"title": "User confirmation",
|
"email_taken": "This e-mail is already in use."
|
||||||
"not_valid": "Something went wrong.",
|
},
|
||||||
"valid": "Your account is confirmed, you can now <a href=\"/login\">log in</a>"
|
"confirm": {
|
||||||
},
|
"title": "User confirmation",
|
||||||
"ordinal": {
|
"not_valid": "Something went wrong.",
|
||||||
"1": "first",
|
"valid": "Your account is confirmed, you can now <a href=\"/login\">log in</a>"
|
||||||
"2": "second",
|
},
|
||||||
"3": "third",
|
"ordinal": {
|
||||||
"4": "fourth",
|
"1": "first",
|
||||||
"5": "fifth",
|
"2": "second",
|
||||||
"-1": "last"
|
"3": "third",
|
||||||
},
|
"4": "fourth",
|
||||||
"validators": {
|
"5": "fifth",
|
||||||
"required": "{fieldName} is required",
|
"-1": "last"
|
||||||
"email": "Insert a valid email"
|
},
|
||||||
},
|
"validators": {
|
||||||
"about": "\n <p><a href='https://gancio.org'>Gancio</a> is a shared agenda for local communities.</p>\n ",
|
"required": "{fieldName} is required",
|
||||||
"oauth": {
|
"email": "Insert a valid email"
|
||||||
"authorization_request": "The application <code>{app}</code> asks for the following authorization on <code>{instance_name}</code>:",
|
},
|
||||||
"redirected_to": "After confirmation you will be redirected to <code>{url}</code>",
|
"about": "\n <p><a href='https://gancio.org'>Gancio</a> is a shared agenda for local communities.</p>\n ",
|
||||||
"scopes": {
|
"oauth": {
|
||||||
"event:write": "Add and edit your events"
|
"authorization_request": "The application <code>{app}</code> asks for the following authorization on <code>{instance_name}</code>:",
|
||||||
}
|
"redirected_to": "After confirmation you will be redirected to <code>{url}</code>",
|
||||||
},
|
"scopes": {
|
||||||
"setup": {
|
"event:write": "Add and edit your events"
|
||||||
"completed": "Setup completed",
|
|
||||||
"completed_description": "<p>You can now login with the following user:<br/><br/>User: <b>{email}</b><br/>Password: <b>{password}<b/></p>",
|
|
||||||
"copy_password_dialog": "Yes, you have to copy the password!",
|
|
||||||
"start": "Start",
|
|
||||||
"https_warning": "You're visiting from HTTP, remember to change baseurl in config.json if you switch to HTTPS!"
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"setup": {
|
||||||
|
"completed": "Setup completed",
|
||||||
|
"completed_description": "<p>You can now login with the following user:<br/><br/>User: <b>{email}</b><br/>Password: <b>{password}<b/></p>",
|
||||||
|
"copy_password_dialog": "Yes, you have to copy the password!",
|
||||||
|
"start": "Start",
|
||||||
|
"https_warning": "You're visiting from HTTP, remember to change baseurl in config.json if you switch to HTTPS!"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
"sequelize-slugify": "^1.6.1",
|
"sequelize-slugify": "^1.6.1",
|
||||||
"sharp": "^0.27.2",
|
"sharp": "^0.27.2",
|
||||||
"sqlite3": "^5.0.11",
|
"sqlite3": "^5.0.11",
|
||||||
"telegraf": "^4.9.0",
|
"telegraf": "^4.9.1",
|
||||||
"tiptap": "^1.32.0",
|
"tiptap": "^1.32.0",
|
||||||
"tiptap-extensions": "^1.35.0",
|
"tiptap-extensions": "^1.35.0",
|
||||||
"umzug": "^2.3.0",
|
"umzug": "^2.3.0",
|
||||||
|
|
|
@ -5,28 +5,69 @@ const config = require('../../config')
|
||||||
|
|
||||||
const pluginController = {
|
const pluginController = {
|
||||||
plugins: [],
|
plugins: [],
|
||||||
getAll(req, res, next) {
|
getAll(_req, res) {
|
||||||
res.json(pluginController.plugins)
|
const settingsController = require('./settings')
|
||||||
|
// return plugins and inner settings
|
||||||
|
const plugins = pluginController.plugins.map(p => {
|
||||||
|
if (settingsController.settings['plugin_' + p.name]) {
|
||||||
|
p.settingsValue = settingsController.settings['plugin_' + p.name]
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
})
|
||||||
|
return res.json(plugins)
|
||||||
},
|
},
|
||||||
|
|
||||||
togglePlugin(req, res, next) {
|
togglePlugin(req, res) {
|
||||||
const plugin = req.params.plugin
|
const settingsController = require('./settings')
|
||||||
if (this.plugins[plugin].enable) {
|
const pluginName = req.params.plugin
|
||||||
|
const pluginSettings = settingsController.settings['plugin_' + pluginName]
|
||||||
|
if (!pluginSettings) { return res.sendStatus(404) }
|
||||||
|
if (!pluginSettings.enable) {
|
||||||
|
pluginController.loadPlugin(pluginName)
|
||||||
|
} else {
|
||||||
|
pluginController.unloadPlugin(pluginName)
|
||||||
}
|
}
|
||||||
|
settingsController.set('plugin_' + pluginName,
|
||||||
|
{ ...pluginSettings, enable: !pluginSettings.enable })
|
||||||
|
res.json()
|
||||||
},
|
},
|
||||||
|
|
||||||
unloadPlugin(plugin) {
|
unloadPlugin(pluginName) {
|
||||||
log.info('Unload plugin ' + plugin)
|
const settingsController = require('./settings')
|
||||||
},
|
const plugin = pluginController.plugins.find(p => p.name === pluginName)
|
||||||
|
const settings = settingsController.settings['plugin_' + pluginName]
|
||||||
loadPlugin(pluginName) {
|
|
||||||
const plugin = this.plugins[pluginName]
|
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
log.warn(`Plugin ${pluginName} not found`)
|
log.warn(`Plugin ${pluginName} not found`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const notifier = require('../../notifier')
|
||||||
|
log.info('Unload plugin ' + plugin)
|
||||||
|
if (typeof plugin.onEventCreate === 'function') {
|
||||||
|
notifier.emitter.off('Create', plugin.onEventCreate)
|
||||||
|
}
|
||||||
|
if (typeof plugin.onEventDelete === 'function') {
|
||||||
|
notifier.emitter.off('Delete', plugin.onEventDelete)
|
||||||
|
}
|
||||||
|
if (typeof plugin.onEventUpdate === 'function') {
|
||||||
|
notifier.emitter.off('Update', plugin.onEventUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.unload && typeof plugin.unload === 'function') {
|
||||||
|
plugin.unload({ settings: settingsController.settings }, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
loadPlugin(pluginName) {
|
||||||
|
const settingsController = require('./settings')
|
||||||
|
const plugin = pluginController.plugins.find(p => p.name === pluginName)
|
||||||
|
const settings = settingsController.settings['plugin_' + pluginName]
|
||||||
|
if (!plugin) {
|
||||||
|
log.warn(`Plugin ${pluginName} not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const notifier = require('../../notifier')
|
||||||
|
log.info('Load plugin ' + plugin)
|
||||||
if (typeof plugin.onEventCreate === 'function') {
|
if (typeof plugin.onEventCreate === 'function') {
|
||||||
notifier.emitter.on('Create', plugin.onEventCreate)
|
notifier.emitter.on('Create', plugin.onEventCreate)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +78,9 @@ const pluginController = {
|
||||||
notifier.emitter.on('Update', plugin.onEventUpdate)
|
notifier.emitter.on('Update', plugin.onEventUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.load({ settings: settingsController.settings }, settingsController.settings.plugins)
|
if (plugin.unload && typeof plugin.unload === 'function') {
|
||||||
|
plugin.load({ settings: settingsController.settings }, settings)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_load() {
|
_load() {
|
||||||
|
@ -46,7 +89,6 @@ const pluginController = {
|
||||||
const plugins_path = config.plugins_path || path.resolve(process.env.cwd || '', 'gancio_plugins')
|
const plugins_path = config.plugins_path || path.resolve(process.env.cwd || '', 'gancio_plugins')
|
||||||
log.info(`Loading plugin ${plugins_path}`)
|
log.info(`Loading plugin ${plugins_path}`)
|
||||||
if (fs.existsSync(plugins_path)) {
|
if (fs.existsSync(plugins_path)) {
|
||||||
const notifier = require('../../notifier')
|
|
||||||
const plugins = fs.readdirSync(plugins_path)
|
const plugins = fs.readdirSync(plugins_path)
|
||||||
.map(e => path.resolve(plugins_path, e, 'index.js'))
|
.map(e => path.resolve(plugins_path, e, 'index.js'))
|
||||||
.filter(index => fs.existsSync(index))
|
.filter(index => fs.existsSync(index))
|
||||||
|
@ -57,19 +99,11 @@ const pluginController = {
|
||||||
const name = plugin.configuration.name
|
const name = plugin.configuration.name
|
||||||
console.log(`Found plugin '${name}'`)
|
console.log(`Found plugin '${name}'`)
|
||||||
pluginController.plugins.push(plugin.configuration)
|
pluginController.plugins.push(plugin.configuration)
|
||||||
|
console.error(settingsController.settings['plugin_' + name])
|
||||||
if (settingsController.settings['plugin_' + name]) {
|
if (settingsController.settings['plugin_' + name]) {
|
||||||
const pluginSetting = settingsController.settings['plugin_' + name]
|
const pluginSetting = settingsController.settings['plugin_' + name]
|
||||||
if (pluginSetting.enable) {
|
if (pluginSetting.enable) {
|
||||||
plugin.load({ settings: settingsController.settings }, settingsController.settings.plugins)
|
pluginController.loadPlugin(name)
|
||||||
if (typeof plugin.onEventCreate === 'function') {
|
|
||||||
notifier.emitter.on('Create', plugin.onEventCreate)
|
|
||||||
}
|
|
||||||
if (typeof plugin.onEventDelete === 'function') {
|
|
||||||
notifier.emitter.on('Delete', plugin.onEventDelete)
|
|
||||||
}
|
|
||||||
if (typeof plugin.onEventUpdate === 'function') {
|
|
||||||
notifier.emitter.on('Update', plugin.onEventUpdate)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
settingsController.set('plugin_' + name, { enable: false })
|
settingsController.set('plugin_' + name, { enable: false })
|
||||||
|
|
|
@ -99,7 +99,7 @@ if (config.status !== 'READY') {
|
||||||
* [usage example](https://framagit.org/les/gancio/-/blob/master/webcomponents/src/GancioEvents.svelte#L18-42)
|
* [usage example](https://framagit.org/les/gancio/-/blob/master/webcomponents/src/GancioEvents.svelte#L18-42)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
api.get('/events', cors, eventController.select)
|
api.get('/events', cors, eventController.select)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new event
|
* Add a new event
|
||||||
|
@ -192,6 +192,7 @@ if (config.status !== 'READY') {
|
||||||
|
|
||||||
// - PLUGINS
|
// - PLUGINS
|
||||||
api.get('/plugins', isAdmin, pluginController.getAll)
|
api.get('/plugins', isAdmin, pluginController.getAll)
|
||||||
|
api.put('/plugin/:plugin', isAdmin, pluginController.togglePlugin)
|
||||||
|
|
||||||
// OAUTH
|
// OAUTH
|
||||||
api.get('/clients', isAuth, oauthController.getClients)
|
api.get('/clients', isAuth, oauthController.getClients)
|
||||||
|
|
|
@ -48,14 +48,14 @@ domPurify.addHook('beforeSanitizeElements', node => {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
randomString (length = 12) {
|
randomString(length = 12) {
|
||||||
const wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
const wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||||
return Array.from(crypto.randomFillSync(new Uint32Array(length)))
|
return Array.from(crypto.randomFillSync(new Uint32Array(length)))
|
||||||
.map(x => wishlist[x % wishlist.length])
|
.map(x => wishlist[x % wishlist.length])
|
||||||
.join('')
|
.join('')
|
||||||
},
|
},
|
||||||
|
|
||||||
sanitizeHTML (html) {
|
sanitizeHTML(html) {
|
||||||
return domPurify.sanitize(html, {
|
return domPurify.sanitize(html, {
|
||||||
ALLOWED_TAGS: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'br', 'i', 'span',
|
ALLOWED_TAGS: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'br', 'i', 'span',
|
||||||
'h6', 'b', 'a', 'li', 'ul', 'ol', 'code', 'blockquote', 'u', 's', 'strong'],
|
'h6', 'b', 'a', 'li', 'ul', 'ol', 'code', 'blockquote', 'u', 's', 'strong'],
|
||||||
|
@ -63,7 +63,7 @@ module.exports = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async setUserLocale (req, res, next) {
|
async setUserLocale(req, res, next) {
|
||||||
// select locale based on cookie? and accept-language header
|
// select locale based on cookie? and accept-language header
|
||||||
acceptLanguage.languages(Object.keys(locales))
|
acceptLanguage.languages(Object.keys(locales))
|
||||||
res.locals.acceptedLocale = acceptLanguage.get(req.headers['accept-language'])
|
res.locals.acceptedLocale = acceptLanguage.get(req.headers['accept-language'])
|
||||||
|
@ -71,28 +71,45 @@ module.exports = {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
async initSettings (_req, res, next) {
|
async initSettings(_req, res, next) {
|
||||||
// initialize settings
|
// initialize settings
|
||||||
res.locals.settings = cloneDeep(settingsController.settings)
|
// res.locals.settings = cloneDeep(settingsController.settings)
|
||||||
delete res.locals.settings.smtp
|
const settings = settingsController.settings
|
||||||
delete res.locals.settings.publicKey
|
res.locals.settings = {
|
||||||
res.locals.settings.baseurl = config.baseurl
|
title: settings.title || config.title,
|
||||||
res.locals.settings.hostname = config.hostname
|
description: settings.description || config.description,
|
||||||
res.locals.settings.title = res.locals.settings.title || config.title
|
baseurl: config.baseurl,
|
||||||
res.locals.settings.description = res.locals.settings.description || config.description
|
hostname: config.hostname,
|
||||||
res.locals.settings.version = pkg.version
|
version: pkg.version,
|
||||||
|
instance_timezone: settings.instance_timezone,
|
||||||
|
instance_locale: settings.instance_locale,
|
||||||
|
instance_name: settings.instance_name,
|
||||||
|
instance_place: settings.instance_place,
|
||||||
|
allow_registration: settings.allow_registration,
|
||||||
|
allow_anon_event: settings.allow_anon_event,
|
||||||
|
allow_recurrent_event: settings.allow_recurrent_event,
|
||||||
|
recurrent_event_visible: settings.recurrent_event_visible,
|
||||||
|
enable_federation: settings.enable_federation,
|
||||||
|
enable_resources: settings.enable_resources,
|
||||||
|
hide_boosts: settings.hide_boosts,
|
||||||
|
enable_trusted_instances: settings.enable_trusted_instances,
|
||||||
|
trusted_instances: settings.trusted_instances,
|
||||||
|
'theme.is_dark': settings['theme.is_dark'],
|
||||||
|
'theme.primary': settings['theme.primary'],
|
||||||
|
footerLinks: settings.footerLinks
|
||||||
|
}
|
||||||
// set user locale
|
// set user locale
|
||||||
res.locals.user_locale = settingsController.user_locale[res.locals.acceptedLocale]
|
res.locals.user_locale = settingsController.user_locale[res.locals.acceptedLocale]
|
||||||
dayjs.tz.setDefault(res.locals.settings.instance_timezone)
|
dayjs.tz.setDefault(res.locals.settings.instance_timezone)
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
serveStatic () {
|
serveStatic() {
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
// serve images/thumb
|
// serve images/thumb
|
||||||
router.use('/media/', express.static(config.upload_path, { immutable: true, maxAge: '1y' } ), (_req, res) => res.sendStatus(404))
|
router.use('/media/', express.static(config.upload_path, { immutable: true, maxAge: '1y' }), (_req, res) => res.sendStatus(404))
|
||||||
router.use('/noimg.svg', express.static('./static/noimg.svg'))
|
router.use('/noimg.svg', express.static('./static/noimg.svg'))
|
||||||
|
|
||||||
router.use('/logo.png', (req, res, next) => {
|
router.use('/logo.png', (req, res, next) => {
|
||||||
const logoPath = res.locals.settings.logo || './static/gancio'
|
const logoPath = res.locals.settings.logo || './static/gancio'
|
||||||
return express.static(logoPath + '.png')(req, res, next)
|
return express.static(logoPath + '.png')(req, res, next)
|
||||||
|
@ -106,12 +123,12 @@ module.exports = {
|
||||||
return router
|
return router
|
||||||
},
|
},
|
||||||
|
|
||||||
logRequest (req, _res, next) {
|
logRequest(req, _res, next) {
|
||||||
log.debug(`${req.method} ${req.path}`)
|
log.debug(`${req.method} ${req.path}`)
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
col (field) {
|
col(field) {
|
||||||
if (config.db.dialect === 'postgres') {
|
if (config.db.dialect === 'postgres') {
|
||||||
return '"' + field.split('.').join('"."') + '"'
|
return '"' + field.split('.').join('"."') + '"'
|
||||||
} else if (config.db.dialect === 'mariadb') {
|
} else if (config.db.dialect === 'mariadb') {
|
||||||
|
@ -121,14 +138,14 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async getImageFromURL (url) {
|
async getImageFromURL(url) {
|
||||||
log.debug(`getImageFromURL ${url}`)
|
log.debug(`getImageFromURL ${url}`)
|
||||||
|
|
||||||
const filename = crypto.randomBytes(16).toString('hex')
|
const filename = crypto.randomBytes(16).toString('hex')
|
||||||
const sharpStream = sharp({ failOnError: true })
|
const sharpStream = sharp({ failOnError: true })
|
||||||
const promises = [
|
const promises = [
|
||||||
sharpStream.clone().resize(500, null, { withoutEnlargement: true }).jpeg({ effort: 6, mozjpeg: true }).toFile(path.resolve(config.upload_path, 'thumb', filename + '.jpg')),
|
sharpStream.clone().resize(500, null, { withoutEnlargement: true }).jpeg({ effort: 6, mozjpeg: true }).toFile(path.resolve(config.upload_path, 'thumb', filename + '.jpg')),
|
||||||
sharpStream.clone().resize(1200, null, { withoutEnlargement: true } ).jpeg({ quality: 95, effort: 6, mozjpeg: true}).toFile(path.resolve(config.upload_path, filename + '.jpg')),
|
sharpStream.clone().resize(1200, null, { withoutEnlargement: true }).jpeg({ quality: 95, effort: 6, mozjpeg: true }).toFile(path.resolve(config.upload_path, filename + '.jpg')),
|
||||||
]
|
]
|
||||||
|
|
||||||
const response = await axios({ method: 'GET', url: encodeURI(url), responseType: 'stream' })
|
const response = await axios({ method: 'GET', url: encodeURI(url), responseType: 'stream' })
|
||||||
|
@ -157,7 +174,7 @@ module.exports = {
|
||||||
* Import events from url
|
* Import events from url
|
||||||
* It does supports ICS and H-EVENT
|
* It does supports ICS and H-EVENT
|
||||||
*/
|
*/
|
||||||
async importURL (req, res) {
|
async importURL(req, res) {
|
||||||
const URL = req.query.URL
|
const URL = req.query.URL
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(URL)
|
const response = await axios.get(URL)
|
||||||
|
@ -210,7 +227,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getWeekdayN (date, n, weekday) {
|
getWeekdayN(date, n, weekday) {
|
||||||
let cursor
|
let cursor
|
||||||
if (n === -1) {
|
if (n === -1) {
|
||||||
cursor = date.endOf('month')
|
cursor = date.endOf('month')
|
||||||
|
@ -227,8 +244,8 @@ module.exports = {
|
||||||
log.debug(cursor)
|
log.debug(cursor)
|
||||||
return cursor
|
return cursor
|
||||||
},
|
},
|
||||||
|
|
||||||
async APRedirect (req, res, next) {
|
async APRedirect(req, res, next) {
|
||||||
const acceptJson = req.accepts('html', 'application/activity+json') === 'application/activity+json'
|
const acceptJson = req.accepts('html', 'application/activity+json') === 'application/activity+json'
|
||||||
if (acceptJson) {
|
if (acceptJson) {
|
||||||
const eventController = require('../server/api/controller/event')
|
const eventController = require('../server/api/controller/event')
|
||||||
|
@ -240,7 +257,7 @@ module.exports = {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
async feedRedirect (req, res, next) {
|
async feedRedirect(req, res, next) {
|
||||||
const accepted = req.accepts('html', 'application/rss+xml', 'text/calendar')
|
const accepted = req.accepts('html', 'application/rss+xml', 'text/calendar')
|
||||||
if (['application/rss+xml', 'text/calendar'].includes(accepted) && /^\/(tag|place|collection)\/.*/.test(req.path)) {
|
if (['application/rss+xml', 'text/calendar'].includes(accepted) && /^\/(tag|place|collection)\/.*/.test(req.path)) {
|
||||||
return res.redirect((accepted === 'application/rss+xml' ? '/feed/rss' : '/feed/ics') + req.path)
|
return res.redirect((accepted === 'application/rss+xml' ? '/feed/rss' : '/feed/ics') + req.path)
|
||||||
|
|
36
yarn.lock
36
yarn.lock
|
@ -4846,11 +4846,6 @@ es-array-method-boxes-properly@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
|
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
|
||||||
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
|
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
|
||||||
|
|
||||||
es-main@^1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/es-main/-/es-main-1.2.0.tgz#b85954f1d9d9f542fcb08685ec19515f969bad16"
|
|
||||||
integrity sha512-A4tCSY43O/mH4rHjG1n0mI4DhK2BmKDr8Lk8PXK/GBB6zxGFGmIW4bbkbTQ2Gi9iNamMZ9vbGrwjZOIeiM7vMw==
|
|
||||||
|
|
||||||
es-to-primitive@^1.2.1:
|
es-to-primitive@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||||
|
@ -8109,11 +8104,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
module-alias@^2.2.2:
|
|
||||||
version "2.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0"
|
|
||||||
integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==
|
|
||||||
|
|
||||||
moment-timezone@^0.5.34:
|
moment-timezone@^0.5.34:
|
||||||
version "0.5.37"
|
version "0.5.37"
|
||||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.37.tgz#adf97f719c4e458fdb12e2b4e87b8bec9f4eef1e"
|
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.37.tgz#adf97f719c4e458fdb12e2b4e87b8bec9f4eef1e"
|
||||||
|
@ -8143,6 +8133,11 @@ move-concurrently@^1.0.1:
|
||||||
rimraf "^2.5.4"
|
rimraf "^2.5.4"
|
||||||
run-queue "^1.0.3"
|
run-queue "^1.0.3"
|
||||||
|
|
||||||
|
mri@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
|
||||||
|
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
|
||||||
|
|
||||||
mrmime@^1.0.0:
|
mrmime@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27"
|
resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27"
|
||||||
|
@ -11672,21 +11667,19 @@ tar@^6.0.2, tar@^6.1.11, tar@^6.1.2:
|
||||||
mkdirp "^1.0.3"
|
mkdirp "^1.0.3"
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
telegraf@^4.9.0:
|
telegraf@^4.9.1:
|
||||||
version "4.9.0"
|
version "4.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/telegraf/-/telegraf-4.9.0.tgz#30997bf6cbc941bff0bb698b13154647fc918032"
|
resolved "https://registry.yarnpkg.com/telegraf/-/telegraf-4.9.1.tgz#bc12e98ea75f2aaf72c5c4a8a0d49c68837bf0b7"
|
||||||
integrity sha512-fL+KLaYRElo4aNtrqAHmFdVsAMHHOHbmdTsAAzMJafhXJu1oYKTRMNipJ/YUvwNd5DnZY+zmGMgVVe1M/dkN4w==
|
integrity sha512-MukWpKvAZ6/HpT3yHXz+jwUf2HsPa9TcsqPLQjJ+kHNGUS2PLgaNX690ExdWmWPuxjVjC4wNHmZ9JetO3C/tVA==
|
||||||
dependencies:
|
dependencies:
|
||||||
abort-controller "^3.0.0"
|
abort-controller "^3.0.0"
|
||||||
debug "^4.3.3"
|
debug "^4.3.3"
|
||||||
es-main "^1.2.0"
|
mri "^1.2.0"
|
||||||
minimist "^1.2.6"
|
|
||||||
module-alias "^2.2.2"
|
|
||||||
node-fetch "^2.6.7"
|
node-fetch "^2.6.7"
|
||||||
p-timeout "^4.1.0"
|
p-timeout "^4.1.0"
|
||||||
safe-compare "^1.1.4"
|
safe-compare "^1.1.4"
|
||||||
sandwich-stream "^2.0.2"
|
sandwich-stream "^2.0.2"
|
||||||
typegram "github:MKRhere/typegram#e2ba9f01f14b96c6dbb1c617e66692a3cc776cf6"
|
typegram "^3.11.0"
|
||||||
|
|
||||||
terminal-link@^2.0.0:
|
terminal-link@^2.0.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
|
@ -12069,9 +12062,10 @@ typedarray@^0.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
|
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
|
||||||
|
|
||||||
"typegram@github:MKRhere/typegram#e2ba9f01f14b96c6dbb1c617e66692a3cc776cf6":
|
typegram@^3.11.0:
|
||||||
version "3.10.0"
|
version "3.11.0"
|
||||||
resolved "https://codeload.github.com/MKRhere/typegram/tar.gz/e2ba9f01f14b96c6dbb1c617e66692a3cc776cf6"
|
resolved "https://registry.yarnpkg.com/typegram/-/typegram-3.11.0.tgz#72e3a8ed0d77864916af465d2c809adf2353ee96"
|
||||||
|
integrity sha512-4p6u+AFognlsDgBue8Hla2jO7Ax+UQXcLa27LC7xDdAeR9LTe+Cr4vJrYpoO1wgj/BFWgXTeboaH/+1YgWyfpA==
|
||||||
|
|
||||||
ua-parser-js@^1.0.2:
|
ua-parser-js@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
|
Loading…
Reference in a new issue