diff --git a/components/Avatar.vue b/components/Avatar.vue index 8c214ff0..49242822 100644 --- a/components/Avatar.vue +++ b/components/Avatar.vue @@ -1,5 +1,5 @@ + + diff --git a/components/Header.vue b/components/Header.vue index 2d1a7a9c..ca321cd4 100644 --- a/components/Header.vue +++ b/components/Header.vue @@ -128,14 +128,14 @@ }); } - // if (this.config.user.enabled) { - // links.push({ - // link: '/' + this.config.user.route, - // icon: 'user', - // text: this.user ? '@' + this.user.username : this.$t('user.header'), - // textLong: this.user ? '@' + this.user.username : this.$t('user.headerLong'), - // }); - // } + if (this.config.user.enabled) { + links.push({ + link: '/' + this.config.user.route, + icon: 'user', + text: this.user ? '@' + this.user.username : this.$t('user.header'), + textLong: this.user ? '@' + this.user.username : this.$t('user.headerLong'), + }); + } return links; }, diff --git a/components/Opinion.vue b/components/Opinion.vue new file mode 100644 index 00000000..d794922d --- /dev/null +++ b/components/Opinion.vue @@ -0,0 +1,38 @@ + + + diff --git a/components/ProfileLink.vue b/components/ProfileLink.vue new file mode 100644 index 00000000..0f5af176 --- /dev/null +++ b/components/ProfileLink.vue @@ -0,0 +1,47 @@ + + + diff --git a/locale/pl/translations.suml b/locale/pl/translations.suml index d2f9d15e..6ca1a0d8 100644 --- a/locale/pl/translations.suml +++ b/locale/pl/translations.suml @@ -625,6 +625,11 @@ user: header: 'Avatar' change: 'Zmień' +profile: + names: 'Imiona' + pronouns: 'Zaimki' + words: 'Słowa' + share: 'Udostępnij' crud: diff --git a/nuxt.config.js b/nuxt.config.js index 5c563962..e4580a6a 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -93,6 +93,7 @@ export default { '/banner': '~/server/banner.js', '/api/nouns': '~/server/nouns.js', '/api/user': '~/server/user.js', + '/api/profile': '~/server/profile.js', }, axios: { baseURL: process.env.BASE_URL + '/api', @@ -136,6 +137,8 @@ export default { } routes.push({ path: '/' + config.template.any.route, component: resolve(__dirname, 'routes/any.vue') }); + routes.push({ path: '/@*', component: resolve(__dirname, 'routes/profile.vue') }); + routes.push({ name: 'all', path: '*', component: resolve(__dirname, 'routes/template.vue') }); }, }, diff --git a/routes/profile.vue b/routes/profile.vue new file mode 100644 index 00000000..db3da2b8 --- /dev/null +++ b/routes/profile.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/server/nouns.js b/server/nouns.js index 6a1d4e31..7abeb437 100644 --- a/server/nouns.js +++ b/server/nouns.js @@ -3,15 +3,7 @@ const SQL = require('sql-template-strings'); import { ulid } from 'ulid' import authenticate from './authenticate'; -const parseQuery = (queryString) => { - const query = {}; - const pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&'); - for (let i = 0; i < pairs.length; i++) { - let pair = pairs[i].split('='); - query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || ''); - } - return query; -} + const getId = url => url.match(/\/([^/]+)$/)[1]; diff --git a/server/profile.js b/server/profile.js new file mode 100644 index 00000000..3f007ea5 --- /dev/null +++ b/server/profile.js @@ -0,0 +1,65 @@ +const dbConnection = require('./db'); +const SQL = require('sql-template-strings'); +import {buildDict, render} from "../src/helpers"; +import { ulid } from 'ulid' +import authenticate from './authenticate'; +import md5 from 'js-md5'; + +const calcAge = birthday => { + if (!birthday) { + return null; + } + + const now = new Date(); + const birth = new Date( + parseInt(birthday.substring(0, 4)), + parseInt(birthday.substring(5, 7)) - 1, + parseInt(birthday.substring(8, 10)) + ); + + const diff = now.getTime() - birth.getTime(); + + return parseInt(Math.floor(diff / 1000 / 60 / 60 / 24 / 365.25)); +} + +const buildProfile = profile => { + return { + id: profile.id, + userId: profile.userId, + username: profile.username, + emailHash: md5(profile.email), + names: JSON.parse(profile.names), + pronouns: JSON.parse(profile.pronouns), + description: profile.description, + age: calcAge(profile.birthday), + links: JSON.parse(profile.links), + flags: JSON.parse(profile.flags), + words: JSON.parse(profile.words), + }; +}; + +export default async function (req, res, next) { + const db = await dbConnection(); + const user = authenticate(req); + + + if (req.method === 'GET' && req.url.startsWith('/get/')) { + const profiles = await db.all(SQL` + SELECT profiles.*, users.username, users.email FROM profiles LEFT JOIN users on users.id == profiles.userId + WHERE users.username = ${req.url.substring(5)} + AND profiles.active = 1 + ORDER BY profiles.locale + `) + return render(res, buildDict(function* () { + for (let profile of profiles) { + yield [profile.locale, buildProfile(profile)]; + } + })); + } + + if (!user || !user.authenticated) { + return render(res, {error: 'unauthorised'}, 401); + } + + return render(res, { error: 'notfound' }, 404); +} diff --git a/src/helpers.js b/src/helpers.js index f76d49d6..a0352bbe 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -72,3 +72,20 @@ export const makeId = (length, characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi return result; } + +export const parseQuery = (queryString) => { + const query = {}; + const pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&'); + for (let i = 0; i < pairs.length; i++) { + let pair = pairs[i].split('='); + query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || ''); + } + return query; +} + +export const render = (res, content, status = 200) => { + res.status = status; + res.setHeader('content-type', 'application/json'); + res.write(JSON.stringify(content)); + res.end(); +} diff --git a/static/flags/agender.png b/static/flags/agender.png new file mode 100644 index 00000000..0a3f828c Binary files /dev/null and b/static/flags/agender.png differ diff --git a/static/flags/european.png b/static/flags/european.png new file mode 100644 index 00000000..708a5fbb Binary files /dev/null and b/static/flags/european.png differ diff --git a/static/flags/nonbinary.png b/static/flags/nonbinary.png new file mode 100644 index 00000000..6e8a50b3 Binary files /dev/null and b/static/flags/nonbinary.png differ diff --git a/static/flags/pansexual.png b/static/flags/pansexual.png new file mode 100644 index 00000000..ea7843a8 Binary files /dev/null and b/static/flags/pansexual.png differ diff --git a/static/flags/polyamorous.png b/static/flags/polyamorous.png new file mode 100644 index 00000000..f70fffea Binary files /dev/null and b/static/flags/polyamorous.png differ diff --git a/static/flags/progress_pride.png b/static/flags/progress_pride.png new file mode 100644 index 00000000..63cbbf3c Binary files /dev/null and b/static/flags/progress_pride.png differ diff --git a/static/flags/transgender.png b/static/flags/transgender.png new file mode 100644 index 00000000..546cac44 Binary files /dev/null and b/static/flags/transgender.png differ