From 7f9df8559139cbda04c480615c4ed25f57c4bbcd Mon Sep 17 00:00:00 2001 From: eug-vs Date: Fri, 26 Jun 2020 21:11:15 +0300 Subject: feat: add verified field to user schema --- models/users/user.schema.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/models/users/user.schema.ts b/models/users/user.schema.ts index ff6cbe9..5969604 100644 --- a/models/users/user.schema.ts +++ b/models/users/user.schema.ts @@ -6,9 +6,20 @@ export interface UserSchema extends Document, Omit { } export const userSchema = new Schema({ - username: String, - password: String, + username: { + type: String, + unique: true, + required: true + }, + password: { + type: String, + required: true + }, email: String, + verified: { + type: Boolean, + default: false + }, avatarUrl: { type: String, required: false -- cgit v1.2.3 From 24376076e0b2c37baaf196f0664078840aeec91b Mon Sep 17 00:00:00 2001 From: eug-vs Date: Fri, 26 Jun 2020 22:12:37 +0300 Subject: feat: sort polls by date (newest on top) --- services/polls/polls.hooks.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/services/polls/polls.hooks.ts b/services/polls/polls.hooks.ts index 13d6f63..524eaee 100644 --- a/services/polls/polls.hooks.ts +++ b/services/polls/polls.hooks.ts @@ -1,6 +1,16 @@ +import _ from 'lodash'; +import { HookContext } from '@feathersjs/feathers'; import convertPoll from '../../hooks/convertPoll'; +const sort = async (context: HookContext): Promise => { + _.set(context, 'params.query.$sort', { createdAt: - 1}); + return context; +} + export default { + before: { + find: sort + }, after: { all: [convertPoll] } -- cgit v1.2.3 From 24119e59528c4425ae255c7381fdba5cfd5a7071 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 00:18:01 +0300 Subject: chore: update which-types --- package-lock.json | 75 +++++++++++++++---------------------------------------- package.json | 2 +- 2 files changed, 21 insertions(+), 56 deletions(-) diff --git a/package-lock.json b/package-lock.json index 779e864..10e4cb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -157,8 +157,7 @@ "@types/bluebird": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.32.tgz", - "integrity": "sha512-dIOxFfI0C+jz89g6lQ+TqhGgPQ0MxSnh/E4xuC0blhFtyW269+mPG5QeLgbdwst/LvdP8o1y0o/Gz5EHXLec/g==", - "dev": true + "integrity": "sha512-dIOxFfI0C+jz89g6lQ+TqhGgPQ0MxSnh/E4xuC0blhFtyW269+mPG5QeLgbdwst/LvdP8o1y0o/Gz5EHXLec/g==" }, "@types/body-parser": { "version": "1.19.0", @@ -173,7 +172,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.2.tgz", "integrity": "sha512-+uWmsejEHfmSjyyM/LkrP0orfE2m5Mx9Xel4tXNeqi1ldK5XMQcDsFkBmLDtuyKUbxj2jGDo0H240fbCRJZo7Q==", - "dev": true, "requires": { "@types/node": "*" } @@ -196,7 +194,6 @@ "version": "2.8.6", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz", "integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==", - "dev": true, "requires": { "@types/express": "*" } @@ -212,8 +209,7 @@ "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==" }, "@types/express": { "version": "4.17.6", @@ -239,8 +235,7 @@ "@types/json-schema": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", - "dev": true + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==" }, "@types/json5": { "version": "0.0.29", @@ -259,8 +254,7 @@ "@types/lodash": { "version": "4.14.155", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.155.tgz", - "integrity": "sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg==", - "dev": true + "integrity": "sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg==" }, "@types/mime": { "version": "2.0.2", @@ -271,7 +265,6 @@ "version": "3.5.20", "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.20.tgz", "integrity": "sha512-BN0wJn670DkivxiP7ZW0InX4qBtX01qITaucD+3A+sTgPQo4XUYay0Y+sGM4MJ9OyKDRlb3RQuVAlyeWzl/NoA==", - "dev": true, "requires": { "@types/bson": "*", "@types/node": "*" @@ -281,7 +274,6 @@ "version": "5.7.23", "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.7.23.tgz", "integrity": "sha512-Yh1vXr+Y+ro887sma0kihtvbazy3prC+gjT0FJZ/Kt6rOQoHnCRm8oiOvDWGncP3YVXAoCj4YeNLp7moIyBKIQ==", - "dev": true, "requires": { "@types/mongodb": "*", "@types/node": "*" @@ -324,7 +316,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.2.0.tgz", "integrity": "sha512-t9RTk/GyYilIXt6BmZurhBzuMT9kLKw3fQoJtK9ayv0tXTlznXEAnx07sCLXdkN3/tZDep1s1CEV95CWuARYWA==", - "dev": true, "requires": { "@typescript-eslint/experimental-utils": "3.2.0", "functional-red-black-tree": "^1.0.1", @@ -336,8 +327,7 @@ "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" } } }, @@ -345,7 +335,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.2.0.tgz", "integrity": "sha512-UbJBsk+xO9dIFKtj16+m42EvUvsjZbbgQ2O5xSTSfVT1Z3yGkL90DVu0Hd3029FZ5/uBgl+F3Vo8FAcEcqc6aQ==", - "dev": true, "requires": { "@types/json-schema": "^7.0.3", "@typescript-eslint/typescript-estree": "3.2.0", @@ -357,7 +346,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.2.0.tgz", "integrity": "sha512-Vhu+wwdevDLVDjK1lIcoD6ZbuOa93fzqszkaO3iCnmrScmKwyW/AGkzc2UvfE5TCoCXqq7Jyt6SOXjsIlpqF4A==", - "dev": true, "requires": { "@types/eslint-visitor-keys": "^1.0.0", "@typescript-eslint/experimental-utils": "3.2.0", @@ -369,7 +357,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.2.0.tgz", "integrity": "sha512-uh+Y2QO7dxNrdLw7mVnjUqkwO/InxEqwN0wF+Za6eo3coxls9aH9kQ/5rSvW2GcNanebRTmsT5w1/92lAOb1bA==", - "dev": true, "requires": { "debug": "^4.1.1", "eslint-visitor-keys": "^1.1.0", @@ -383,8 +370,7 @@ "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" } } }, @@ -522,8 +508,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-arraybuffer": { "version": "0.1.5", @@ -603,7 +588,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -746,8 +730,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "config": { "version": "3.3.1", @@ -1215,7 +1198,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" @@ -1225,7 +1207,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } @@ -1233,8 +1214,7 @@ "eslint-visitor-keys": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", - "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==", - "dev": true + "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==" }, "espree": { "version": "7.1.0", @@ -1274,7 +1254,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, "requires": { "estraverse": "^4.1.0" } @@ -1282,8 +1261,7 @@ "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, "esutils": { "version": "2.0.3", @@ -1478,8 +1456,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.1", @@ -1490,14 +1467,12 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1630,7 +1605,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -1740,8 +1714,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -1753,7 +1726,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -2002,7 +1974,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2197,7 +2168,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -2303,8 +2273,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -2455,8 +2424,7 @@ "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" }, "require_optional": { "version": "1.0.1", @@ -2990,14 +2958,12 @@ "tslib": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, "requires": { "tslib": "^1.8.1" } @@ -3096,9 +3062,9 @@ } }, "which-types": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/which-types/-/which-types-1.4.1.tgz", - "integrity": "sha512-ZtN3cDwz/fQbJBwrItsZ0jpGafReTd/fIffHNQtFW4THrZqi8z4qnFTbyu1M6LnAmPlwU/FaRLZPfd67ZQ4mFw==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/which-types/-/which-types-1.4.2.tgz", + "integrity": "sha512-nwcohvhH+VEA11cReLi/BgeuKHJYH7VM2BWe9OIX89CB+iaZ0+wb6oLFcIP6Vp6jw3k93yoPMe9pMBsOi4kj6w==" }, "word-wrap": { "version": "1.2.3", @@ -3109,8 +3075,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", diff --git a/package.json b/package.json index ca39263..b5e95bc 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "mongoose": "^5.9.18", "ts-node": "^8.10.2", "typescript": "^3.9.5", - "which-types": "^1.4.1" + "which-types": "^1.4.2" }, "repository": { "type": "git", -- cgit v1.2.3 From 9a488369a481d92fed348df3de71bf612c4183d5 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 00:18:32 +0300 Subject: feat: create feed service --- services/feed/feed.class.ts | 27 +++++++++++++++++++++++++++ services/feed/feed.service.ts | 7 +++++++ services/index.ts | 2 ++ 3 files changed, 36 insertions(+) create mode 100644 services/feed/feed.class.ts create mode 100644 services/feed/feed.service.ts diff --git a/services/feed/feed.class.ts b/services/feed/feed.class.ts new file mode 100644 index 0000000..8c7cd0b --- /dev/null +++ b/services/feed/feed.class.ts @@ -0,0 +1,27 @@ +import _ from 'lodash'; +import { Application } from '@feathersjs/express'; +import { Params } from '@feathersjs/feathers'; +import { Poll } from 'which-types'; + +import { PollSchema } from '../../models/polls/poll.schema'; +import PollModel from '../../models/polls/poll.model'; + + +export default class Feed { + app!: Application; + + async find(params: Params): Promise { + return this.app.service('polls') + .find(params) + .then( // Move new verified polls on top + (polls: Poll[]) => _.sortBy(polls, poll => poll.author.verified && !poll.userChoice) + ).then( // But all seen posts go down + (polls: Poll[]) => _.sortBy(polls, poll => !!poll.userChoice) + ); + } + + setup (app: Application) { + this.app = app; + } +} + diff --git a/services/feed/feed.service.ts b/services/feed/feed.service.ts new file mode 100644 index 0000000..f641425 --- /dev/null +++ b/services/feed/feed.service.ts @@ -0,0 +1,7 @@ +import { Application } from '@feathersjs/express'; +import Feed from './feed.class'; + +export default (app: Application): void => { + app.use('/feed', new Feed()); +}; + diff --git a/services/index.ts b/services/index.ts index bdce04f..1763a17 100644 --- a/services/index.ts +++ b/services/index.ts @@ -4,6 +4,7 @@ import Polls from './polls/polls.service'; import Profiles from './profiles/profiles.service'; import Votes from './votes/votes.service'; import Auth from './auth/auth.service'; +import Feed from './feed/feed.service'; import tryAuthenticate from '../hooks/tryAuthenticate'; import logging from '../hooks/logging'; @@ -15,6 +16,7 @@ export default (app: Application): void => { app.configure(Polls); app.configure(Profiles); app.configure(Votes); + app.configure(Feed); app.hooks({ before: { -- cgit v1.2.3 From 0a78ac48ed5ae37f88e5f36194953424a5bc18a0 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 00:53:48 +0300 Subject: refactor: move sortByDate hook to global hooks --- hooks/sortByDate.ts | 8 ++++++++ services/polls/polls.hooks.ts | 12 +++--------- 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 hooks/sortByDate.ts diff --git a/hooks/sortByDate.ts b/hooks/sortByDate.ts new file mode 100644 index 0000000..4a20920 --- /dev/null +++ b/hooks/sortByDate.ts @@ -0,0 +1,8 @@ +import _ from 'lodash'; +import { HookContext } from '@feathersjs/feathers'; + +export default async (context: HookContext): Promise => { + _.set(context, 'params.query.$sort', { createdAt: - 1}); + return context; +} + diff --git a/services/polls/polls.hooks.ts b/services/polls/polls.hooks.ts index 524eaee..77fcc7a 100644 --- a/services/polls/polls.hooks.ts +++ b/services/polls/polls.hooks.ts @@ -1,18 +1,12 @@ -import _ from 'lodash'; -import { HookContext } from '@feathersjs/feathers'; import convertPoll from '../../hooks/convertPoll'; - -const sort = async (context: HookContext): Promise => { - _.set(context, 'params.query.$sort', { createdAt: - 1}); - return context; -} +import sortByDate from '../../hooks/sortByDate'; export default { before: { - find: sort + find: sortByDate }, after: { - all: [convertPoll] + all: convertPoll } }; -- cgit v1.2.3 From 7c2d12b4f809563cc08e86229359251674b745ce Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 01:17:42 +0300 Subject: refactor: improve Feed service --- services/feed/feed.class.ts | 12 +----------- services/feed/feed.hooks.ts | 28 ++++++++++++++++++++++++++++ services/feed/feed.service.ts | 3 +++ 3 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 services/feed/feed.hooks.ts diff --git a/services/feed/feed.class.ts b/services/feed/feed.class.ts index 8c7cd0b..3a2ffe4 100644 --- a/services/feed/feed.class.ts +++ b/services/feed/feed.class.ts @@ -1,23 +1,13 @@ -import _ from 'lodash'; import { Application } from '@feathersjs/express'; import { Params } from '@feathersjs/feathers'; import { Poll } from 'which-types'; -import { PollSchema } from '../../models/polls/poll.schema'; -import PollModel from '../../models/polls/poll.model'; - export default class Feed { app!: Application; async find(params: Params): Promise { - return this.app.service('polls') - .find(params) - .then( // Move new verified polls on top - (polls: Poll[]) => _.sortBy(polls, poll => poll.author.verified && !poll.userChoice) - ).then( // But all seen posts go down - (polls: Poll[]) => _.sortBy(polls, poll => !!poll.userChoice) - ); + return this.app.service('polls').find(params); } setup (app: Application) { diff --git a/services/feed/feed.hooks.ts b/services/feed/feed.hooks.ts new file mode 100644 index 0000000..0e201db --- /dev/null +++ b/services/feed/feed.hooks.ts @@ -0,0 +1,28 @@ +import _ from 'lodash'; +import { HookContext } from '@feathersjs/feathers'; + + +const raiseNewVerifedPolls = async (context: HookContext): Promise => { + // Raise unseen verified polls to the very top + context.result = _.sortBy( + context.result, + poll => !(poll.author.verified && !poll.userChoice) + ); + return context; +}; + +const lowerOldPolls = async (context: HookContext): Promise => { + // Move all seen polls down + context.result = _.sortBy( + context.result, + poll => !!poll.userChoice + ); + return context; +}; + +export default { + after: { + find: [raiseNewVerifedPolls, lowerOldPolls] + } +}; + diff --git a/services/feed/feed.service.ts b/services/feed/feed.service.ts index f641425..d326656 100644 --- a/services/feed/feed.service.ts +++ b/services/feed/feed.service.ts @@ -1,7 +1,10 @@ import { Application } from '@feathersjs/express'; import Feed from './feed.class'; +import hooks from './feed.hooks'; + export default (app: Application): void => { app.use('/feed', new Feed()); + app.service('feed').hooks(hooks); }; -- cgit v1.2.3 From d7d65bbde562519f6a78d90b8ca11a3bdd0420a1 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 01:24:25 +0300 Subject: refactor: simplify profile service --- services/profiles/profiles.class.ts | 19 +++++++++++++++---- services/profiles/profiles.hooks.ts | 8 -------- services/profiles/profiles.service.ts | 3 --- 3 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 services/profiles/profiles.hooks.ts diff --git a/services/profiles/profiles.class.ts b/services/profiles/profiles.class.ts index 52d6b47..564e2a6 100644 --- a/services/profiles/profiles.class.ts +++ b/services/profiles/profiles.class.ts @@ -1,9 +1,20 @@ -import { PollSchema } from '../../models/polls/poll.schema'; -import PollModel from '../../models/polls/poll.model'; +import { Application } from '@feathersjs/express'; +import { Poll } from 'which-types'; + export default class Profiles { - async get(id: string): Promise { - return PollModel.find({ authorId: id }).lean(); + app!: Application; + + async get(id: string): Promise { + return this.app.service('polls').find({ + query: { + authorId: id + } + }); + } + + setup (app: Application) { + this.app = app; } } diff --git a/services/profiles/profiles.hooks.ts b/services/profiles/profiles.hooks.ts deleted file mode 100644 index 13d6f63..0000000 --- a/services/profiles/profiles.hooks.ts +++ /dev/null @@ -1,8 +0,0 @@ -import convertPoll from '../../hooks/convertPoll'; - -export default { - after: { - all: [convertPoll] - } -}; - diff --git a/services/profiles/profiles.service.ts b/services/profiles/profiles.service.ts index e860426..ae06cf9 100644 --- a/services/profiles/profiles.service.ts +++ b/services/profiles/profiles.service.ts @@ -1,10 +1,7 @@ import { Application } from '@feathersjs/express'; import Profiles from './profiles.class'; -import hooks from './profiles.hooks'; - export default (app: Application): void => { app.use('/profiles', new Profiles()); - app.service('profiles').hooks(hooks); }; -- cgit v1.2.3 From a8c74bf2c5b8a8cc0bfd0f1d082eb3bf8357f6bc Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 01:26:03 +0300 Subject: style: fix linting errors --- hooks/sortByDate.ts | 4 ++-- services/feed/feed.class.ts | 2 +- services/profiles/profiles.class.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hooks/sortByDate.ts b/hooks/sortByDate.ts index 4a20920..9dd1222 100644 --- a/hooks/sortByDate.ts +++ b/hooks/sortByDate.ts @@ -2,7 +2,7 @@ import _ from 'lodash'; import { HookContext } from '@feathersjs/feathers'; export default async (context: HookContext): Promise => { - _.set(context, 'params.query.$sort', { createdAt: - 1}); + _.set(context, 'params.query.$sort', { createdAt: -1 }); return context; -} +}; diff --git a/services/feed/feed.class.ts b/services/feed/feed.class.ts index 3a2ffe4..ceb86e6 100644 --- a/services/feed/feed.class.ts +++ b/services/feed/feed.class.ts @@ -10,7 +10,7 @@ export default class Feed { return this.app.service('polls').find(params); } - setup (app: Application) { + setup(app: Application): void { this.app = app; } } diff --git a/services/profiles/profiles.class.ts b/services/profiles/profiles.class.ts index 564e2a6..3461cbc 100644 --- a/services/profiles/profiles.class.ts +++ b/services/profiles/profiles.class.ts @@ -13,7 +13,7 @@ export default class Profiles { }); } - setup (app: Application) { + setup(app: Application): void { this.app = app; } } -- cgit v1.2.3 From 5b4b64905a1b59002bbd1edfdc77c9e422e33334 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 16:16:08 +0300 Subject: chore: install feathers-hooks-common --- package-lock.json | 51 +++++++++++++++++++++++++++++++++++++++++---------- package.json | 1 + 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10e4cb6..c0621bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,11 @@ } } }, + "@feathers-plus/batch-loader": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@feathers-plus/batch-loader/-/batch-loader-0.3.6.tgz", + "integrity": "sha512-r+n31iZ/B5Rl1mLkC9/S20UI445MdkZvE3VBmjupep2t8OuyTYHPkFEgR25HY6khH+RothK1VL3B5eumk9N2QQ==" + }, "@feathersjs/adapter-commons": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/@feathersjs/adapter-commons/-/adapter-commons-4.5.2.tgz", @@ -404,7 +409,6 @@ "version": "6.12.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1345,14 +1349,12 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", @@ -1360,6 +1362,23 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "feathers-hooks-common": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/feathers-hooks-common/-/feathers-hooks-common-5.0.3.tgz", + "integrity": "sha512-Irw7mVecC2im9Pemr4yGyO8XXxFhlqn4rnsc5iSNMSmO78ta1QaHUfiZddmquA0u0KTFyk2crQK4mcHq8grzXA==", + "requires": { + "@feathers-plus/batch-loader": "^0.3.6", + "@feathersjs/commons": "^4.5.3", + "@feathersjs/errors": "^4.5.3", + "@feathersjs/feathers": "^4.5.3", + "ajv": "^6.12.2", + "debug": "^4.1.1", + "graphql": "^15.0.0", + "lodash": "^4.17.15", + "process": "0.11.10", + "traverse": "^0.6.6" + } + }, "feathers-mongoose": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/feathers-mongoose/-/feathers-mongoose-8.3.0.tgz", @@ -1506,6 +1525,11 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, + "graphql": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.1.0.tgz", + "integrity": "sha512-0TVyfOlCGhv/DBczQkJmwXOK6fjWkjzY3Pt7wY8i0gcYXq8aogG3weCsg48m72lywKSeOqedEHvVPOvZvSD51Q==" + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1784,8 +1808,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -2322,6 +2345,11 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -2345,8 +2373,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { "version": "6.7.0", @@ -2931,6 +2958,11 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" + }, "ts-node": { "version": "8.10.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", @@ -3011,7 +3043,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index b5e95bc..c55255c 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@typescript-eslint/parser": "^3.2.0", "bluebird": "^3.7.2", "cors": "^2.8.5", + "feathers-hooks-common": "^5.0.3", "feathers-mongoose": "^8.3.0", "lodash": "^4.17.15", "mongoose": "^5.9.18", -- cgit v1.2.3 From 69b212128435cab2919f642fd8352b0b6cf93f83 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 16:25:59 +0300 Subject: feat: add isAuthenticated hook --- hooks/isAuthenticated.ts | 9 +++++++++ hooks/requireAuth.ts | 13 ++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 hooks/isAuthenticated.ts diff --git a/hooks/isAuthenticated.ts b/hooks/isAuthenticated.ts new file mode 100644 index 0000000..d0da8b6 --- /dev/null +++ b/hooks/isAuthenticated.ts @@ -0,0 +1,9 @@ +import { HookContext } from '@feathersjs/feathers'; +import { authenticate } from '@feathersjs/authentication'; + + +export default async (context: HookContext): Promise => { + console.log(context.params.authenticated); + return context.params.authenticated || false; +}; + diff --git a/hooks/requireAuth.ts b/hooks/requireAuth.ts index 52e8974..ac46e22 100644 --- a/hooks/requireAuth.ts +++ b/hooks/requireAuth.ts @@ -1,10 +1,9 @@ +import { iff, isNot } from 'feathers-hooks-common'; import { NotAuthenticated } from '@feathersjs/errors'; -import { HookContext } from '@feathersjs/feathers'; +import isAuthenticated from './isAuthenticated'; -export default async (context: HookContext): Promise => { - if (!context.params.authenticated) { - throw new NotAuthenticated('This endpoint requires auth!'); - } - return context; -}; +export default iff( + isNot(isAuthenticated), + () => { throw new NotAuthenticated('This endpoint requires auth!') } +); -- cgit v1.2.3 From 8f5f077c318e9b466cc47ebab548ea0cd69052f0 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 16:26:21 +0300 Subject: feat: only modify polls order for authorized users --- services/feed/feed.hooks.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/services/feed/feed.hooks.ts b/services/feed/feed.hooks.ts index 0e201db..33c6e71 100644 --- a/services/feed/feed.hooks.ts +++ b/services/feed/feed.hooks.ts @@ -1,6 +1,7 @@ import _ from 'lodash'; import { HookContext } from '@feathersjs/feathers'; - +import { iff, combine } from 'feathers-hooks-common'; +import isAuthenticated from '../../hooks/isAuthenticated'; const raiseNewVerifedPolls = async (context: HookContext): Promise => { // Raise unseen verified polls to the very top @@ -22,7 +23,10 @@ const lowerOldPolls = async (context: HookContext): Promise => { export default { after: { - find: [raiseNewVerifedPolls, lowerOldPolls] + find: [ + iff(isAuthenticated, raiseNewVerifedPolls), + iff(isAuthenticated, lowerOldPolls), + ] } }; -- cgit v1.2.3 From 0a6a6be1b43635c60e76669ac2a7ee8581d9b183 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 27 Jun 2020 16:40:07 +0300 Subject: style: fix linting errors --- hooks/isAuthenticated.ts | 2 -- hooks/requireAuth.ts | 4 +++- services/feed/feed.hooks.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hooks/isAuthenticated.ts b/hooks/isAuthenticated.ts index d0da8b6..50290c8 100644 --- a/hooks/isAuthenticated.ts +++ b/hooks/isAuthenticated.ts @@ -1,6 +1,4 @@ import { HookContext } from '@feathersjs/feathers'; -import { authenticate } from '@feathersjs/authentication'; - export default async (context: HookContext): Promise => { console.log(context.params.authenticated); diff --git a/hooks/requireAuth.ts b/hooks/requireAuth.ts index ac46e22..ba08f57 100644 --- a/hooks/requireAuth.ts +++ b/hooks/requireAuth.ts @@ -4,6 +4,8 @@ import isAuthenticated from './isAuthenticated'; export default iff( isNot(isAuthenticated), - () => { throw new NotAuthenticated('This endpoint requires auth!') } + () => { + throw new NotAuthenticated('This endpoint requires auth!'); + } ); diff --git a/services/feed/feed.hooks.ts b/services/feed/feed.hooks.ts index 33c6e71..54f6d61 100644 --- a/services/feed/feed.hooks.ts +++ b/services/feed/feed.hooks.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; import { HookContext } from '@feathersjs/feathers'; -import { iff, combine } from 'feathers-hooks-common'; +import { iff } from 'feathers-hooks-common'; import isAuthenticated from '../../hooks/isAuthenticated'; const raiseNewVerifedPolls = async (context: HookContext): Promise => { @@ -25,7 +25,7 @@ export default { after: { find: [ iff(isAuthenticated, raiseNewVerifedPolls), - iff(isAuthenticated, lowerOldPolls), + iff(isAuthenticated, lowerOldPolls) ] } }; -- cgit v1.2.3