diff --git a/db/migrations/1584861008595-CreateUserTable.ts b/db/migrations-old/1584861008595-CreateUserTable.ts similarity index 100% rename from db/migrations/1584861008595-CreateUserTable.ts rename to db/migrations-old/1584861008595-CreateUserTable.ts diff --git a/db/migrations/1587075769273-True.ts b/db/migrations-old/1587075769273-True.ts similarity index 86% rename from db/migrations/1587075769273-True.ts rename to db/migrations-old/1587075769273-True.ts index 12c466c..4ad677a 100644 --- a/db/migrations/1587075769273-True.ts +++ b/db/migrations-old/1587075769273-True.ts @@ -5,8 +5,6 @@ export class True1587075769273 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(`CREATE TABLE "reviews" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "collection_item_id" character varying NOT NULL, "rating" character varying, "title" character varying, "review_text" character varying, CONSTRAINT "PK_231ae565c273ee700b283f15c1d" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "rating"`, undefined); - await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "review"`, undefined); await queryRunner.query(`ALTER TABLE "users" ADD "password" character varying NOT NULL`, undefined); await queryRunner.query(`ALTER TABLE "users" ADD "salt" character varying NOT NULL`, undefined); await queryRunner.query(`ALTER TABLE "users" ADD "account_settings" jsonb`, undefined); @@ -22,8 +20,6 @@ export class True1587075769273 implements MigrationInterface { await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "account_settings"`, undefined); await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "salt"`, undefined); await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "password"`, undefined); - await queryRunner.query(`ALTER TABLE "items" ADD "review" character varying`, undefined); - await queryRunner.query(`ALTER TABLE "items" ADD "rating" character varying`, undefined); await queryRunner.query(`DROP TABLE "reviews"`, undefined); } diff --git a/db/migrations/1587076386589-True.ts b/db/migrations/1587076386589-True.ts new file mode 100644 index 0000000..fa0eb4c --- /dev/null +++ b/db/migrations/1587076386589-True.ts @@ -0,0 +1,26 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class True1587076386589 implements MigrationInterface { + name = 'True1587076386589' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "users" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "username" character varying NOT NULL, "email" character varying, "password" character varying NOT NULL, "salt" character varying NOT NULL, "bio" character varying, "account_settings" jsonb, CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email"), CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE TABLE "items" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "mbid" character varying, "rym_id" integer, "spotify_id" character varying, "title" character varying NOT NULL, "disambiguation" character varying, "artist" character varying NOT NULL, CONSTRAINT "PK_ba5885359424c15ca6b9e79bcf6" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE TABLE "reviews" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "collection_item_id" character varying NOT NULL, "rating" character varying, "title" character varying, "review_text" character varying, CONSTRAINT "PK_231ae565c273ee700b283f15c1d" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE TABLE "collection_items" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "custom_title" character varying, "custom_artist" character varying, "user_id" character varying NOT NULL, "item_details_id" character varying NOT NULL, "plays" integer DEFAULT 0, CONSTRAINT "PK_5f299da96958a920ab58871ea57" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`ALTER TABLE "reviews" ADD CONSTRAINT "FK_fc090d3e6b0a3b369f03d9aa673" FOREIGN KEY ("collection_item_id") REFERENCES "collection_items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" ADD CONSTRAINT "FK_11904cd0bab7d35969089548db8" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" ADD CONSTRAINT "FK_08f049748e8a0c61e1c7b247028" FOREIGN KEY ("item_details_id") REFERENCES "items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "collection_items" DROP CONSTRAINT "FK_08f049748e8a0c61e1c7b247028"`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" DROP CONSTRAINT "FK_11904cd0bab7d35969089548db8"`, undefined); + await queryRunner.query(`ALTER TABLE "reviews" DROP CONSTRAINT "FK_fc090d3e6b0a3b369f03d9aa673"`, undefined); + await queryRunner.query(`DROP TABLE "collection_items"`, undefined); + await queryRunner.query(`DROP TABLE "reviews"`, undefined); + await queryRunner.query(`DROP TABLE "items"`, undefined); + await queryRunner.query(`DROP TABLE "users"`, undefined); + } + +} diff --git a/package.json b/package.json index a9160a3..d35b12c 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,9 @@ ] }, "dependencies": { + "@types/bcrypt": "^3.0.0", "@types/sqlite3": "^3.1.5", + "bcrypt": "^4.0.1", "dotenv": "^8.0.0", "dotenvi": "^0.6.0", "reflect-metadata": "^0.1.13", diff --git a/src/modules/user/user.service.ts b/src/modules/user/user.service.ts index 6676c8a..be69645 100644 --- a/src/modules/user/user.service.ts +++ b/src/modules/user/user.service.ts @@ -2,12 +2,40 @@ import { Service } from 'typedi'; import { Repository } from 'typeorm'; import { InjectRepository } from 'typeorm-typedi-extensions'; import { BaseService } from 'warthog'; - +import * as bcrypt from 'bcrypt'; import { User } from './user.model'; +import { UserCreateInput } from '../../../generated'; +import { CollectionItem } from '../collection-item/collection-item.model'; @Service('UserService') export class UserService extends BaseService { constructor(@InjectRepository(User) protected readonly repository: Repository) { super(User, repository); } + + async create(user: UserCreateInput, userId: string) { + const salt = await bcrypt.genSalt(); + user.password = await bcrypt.hash(user.password, salt); + const collection: CollectionItem[] = []; + + const payload = { + ...user, + salt, + collection, + } + + return super.create(payload, userId); + } + + // TODO: Sign in + // async validateUserPassword(authCredentialsInput: UserCreateInput): Promise { + // const { username, password } = authCredentialsInput; + // const user = await this.findOne({username}); + + // if (user && user.password === bcrypt.hash(user.password, user.salt)) { + // return user.username; + // } else { + // return 'user not found'; + // } + // } } diff --git a/yarn.lock b/yarn.lock index 64e375e..cadfcef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -486,6 +486,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bcrypt@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-3.0.0.tgz#851489a9065a067cb7f3c9cbe4ce9bed8bba0876" + integrity sha512-nohgNyv+1ViVcubKBh0+XiNJ3dO8nYu///9aJ4cgSqv70gBL+94SNy/iC2NLzKPT2Zt/QavrOkBVbZRLZmw6NQ== + "@types/bluebird@^3.5.20": version "3.5.30" resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.30.tgz#ee034a0eeea8b84ed868b1aa60d690b08a6cfbc5" @@ -1421,6 +1426,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bcrypt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-4.0.1.tgz#06e21e749a061020e4ff1283c1faa93187ac57fe" + integrity sha512-hSIZHkUxIDS5zA2o00Kf2O5RfVbQ888n54xQoF/eIaquU4uaLxK8vhhBdktd0B3n2MjkcAWzv4mnhogykBKOUQ== + dependencies: + node-addon-api "^2.0.0" + node-pre-gyp "0.14.0" + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -4283,6 +4296,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-addon-api@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b" + integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA== + node-emoji@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -4316,6 +4334,22 @@ node-notifier@^5.4.0, node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" +node-pre-gyp@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" + integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4.4.2" + node-pre-gyp@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" @@ -5826,7 +5860,7 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -tar@^4: +tar@^4, tar@^4.4.2: version "4.4.13" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==