Преглед на файлове

feat: Move types into shared package

tags/v0.1.0
Dale преди 3 месеца
родител
ревизия
e2213da0c0
променени са 55 файла, в които са добавени 1149 реда и са изтрити 1473 реда
  1. +0
    -0
     
  2. +0
    -0
     
  3. +0
    -0
     
  4. +0
    -0
     
  5. +1
    -1
      bin/testServer.sh
  6. +0
    -0
     
  7. +0
    -0
     
  8. +3
    -2
      default.nix
  9. +0
    -0
     
  10. +0
    -0
     
  11. +0
    -0
     
  12. +0
    -0
     
  13. +0
    -0
     
  14. +0
    -0
     
  15. +6
    -2
      package.json
  16. +1
    -1
      src/server/api/v1/handlers/activities.ts
  17. +6
    -3
      src/server/api/v1/handlers/auth.ts
  18. +1
    -1
      src/server/api/v1/handlers/channels.ts
  19. +2
    -2
      src/server/api/v1/handlers/streamkeys.ts
  20. +7
    -3
      src/server/api/v1/handlers/users.ts
  21. +0
    -0
     
  22. +0
    -21
      src/server/api/v1/interfaces/IActivity.ts
  23. +0
    -17
      src/server/api/v1/interfaces/IChannel.ts
  24. +0
    -11
      src/server/api/v1/interfaces/ISession.ts
  25. +0
    -10
      src/server/api/v1/interfaces/IStreamKey.ts
  26. +0
    -26
      src/server/api/v1/interfaces/IUser.ts
  27. +0
    -0
     
  28. +0
    -9
      src/server/api/v1/schemas/activity/createActivity.json
  29. +0
    -9
      src/server/api/v1/schemas/auth/loginRequest.json
  30. +0
    -11
      src/server/api/v1/schemas/channel/createChannel.json
  31. +0
    -9
      src/server/api/v1/schemas/streamkeys/createStreamkey.json
  32. +0
    -10
      src/server/api/v1/schemas/user/createUser.json
  33. +0
    -9
      src/server/api/v1/schemas/user/updateUser.json
  34. +0
    -0
     
  35. +4
    -3
      src/server/db/Channels.ts
  36. +1
    -3
      src/server/db/Sessions.ts
  37. +1
    -1
      src/server/db/Streamkeys.ts
  38. +1
    -1
      src/server/db/Users.ts
  39. +0
    -0
     
  40. +2
    -2
      src/server/lib/crypto.ts
  41. +0
    -8
      src/server/lib/db/interfaces.ts
  42. +3
    -3
      src/server/lib/http/interfaces.ts
  43. +0
    -0
     
  44. +0
    -0
     
  45. +1
    -1
      src/server/lib/http/response.ts
  46. +2
    -6
      src/server/lib/validation/errors.ts
  47. +0
    -0
     
  48. +8
    -3
      src/server/server.ts
  49. +0
    -52
      src/shared/lib/const.ts
  50. +0
    -6
      src/types/typings.d.ts
  51. +0
    -0
     
  52. +3
    -1
      test/server/lib/crypto.spec.ts
  53. +0
    -0
     
  54. +0
    -0
     
  55. +1096
    -1226
      yarn.lock




+ 1
- 1
bin/testServer.sh Целия файл

@@ -4,5 +4,5 @@ PG_USER=${1-$USER};

psql postgres $USER -c "drop database if exists miracle_test;";
psql postgres $USER -c "create database miracle_test;";
yarn migration:test;
yarn migrate:test &> /dev/null;
yarn test:server;



+ 3
- 2
default.nix Целия файл

@@ -9,8 +9,9 @@ stdenv.mkDerivation {
export PATH="$PATH:$PWD/node_modules/.bin"
'';

buildInputs = [
buildInputs = with pkgs; [
yarn automake autoconf m4 git bash
nodejs-8_x libpng libGL gcc
nodejs-14_x libpng libGL gcc
nodePackages.typescript-language-server
];
}







+ 6
- 2
package.json Целия файл

@@ -6,14 +6,15 @@
"license": "MIT",
"private": false,
"scripts": {
"test": "NODE_PATH=./src ./node_modules/.bin/mocha",
"test": "sh ./bin/testServer.sh",
"test:mocha": "NODE_PATH=./src ./node_modules/.bin/mocha",
"watch:server": "./node_modules/.bin/nodemon -e ts --exec \"yarn run:server\"",
"run:server": "./node_modules/.bin/ts-node -r ./node_modules/tsconfig-paths/register ./src/server/server.ts",
"build:server": "rm -rf ./dist/* && ./node_modules/.bin/tsc",
"test:server": "NODE_PATH=./src ./node_modules/.bin/mocha -r ts-node/register -r tsconfig-paths/register test/server/**/*.spec.ts --configPath ./config/test.json",
"migrate:add": "./node_modules/.bin/knex migrate:make --migrations-directory .\\migrations",
"migrate:local": "./node_modules/.bin/knex migrate:latest",
"migrate:test": "yarn migration:local ./config/test.json"
"migrate:test": "yarn migrate:local ./config/test.json"
},
"dependencies": {
"@types/js-md5": "^0.4.2",
@@ -23,9 +24,11 @@
"js-md5": "^0.7.3",
"knex": "^0.16.5",
"minimist": "^1.2.0",
"miracle-tv-shared": "git+https://code.gensokyo.social/Gensokyo.social/miracle-tv-shared.git",
"pg": "^7.11.0",
"ramda": "^0.26.1",
"sqlite3": "^4.0.8",
"supertest": "^4.0.2",
"uuid": "^3.3.2"
},
"devDependencies": {
@@ -37,6 +40,7 @@
"@types/mocha": "^5.2.6",
"@types/node": "^12.0.2",
"@types/ramda": "^0.26.8",
"@types/supertest": "^2.0.10",
"@types/uuid": "^3.4.4",
"chai": "^4.2.0",
"json-loader": "^0.5.7",


+ 1
- 1
src/server/api/v1/handlers/activities.ts Целия файл

@@ -13,7 +13,7 @@ import { getIdFromParams } from 'server/lib/http/request';
import { isAdmin, isMod } from 'server/lib/crypto';

import { authenticateUser, acceptsSchema } from 'server/lib/http/middleware';
import createActivityJson from 'server/api/v1/schemas/activity/createActivity.json';
import createActivityJson from 'miracle-tv-shared/src/types/api/v1/schemas/activity/createActivity.json';

function getList (_: any, res: Response) {
Activities.getActivities().then(sendData(res));


+ 6
- 3
src/server/api/v1/handlers/auth.ts Целия файл

@@ -2,16 +2,18 @@ import Users from 'server/db/Users';
import Sessions from 'server/db/Sessions';
import { Router, Response } from 'express';

import ISession from 'server/api/v1/interfaces/ISession';
import ISession from 'miracle-tv-shared/src/types/api/v1/interfaces/ISession';

import { acceptsSchema, authenticateUser } from 'server/lib/http/middleware';
import * as loginSchema from 'server/api/v1/schemas/auth/loginRequest.json';
import * as createUserSchema from 'server/api/v1/schemas/user/createUser.json';
import loginSchema from 'miracle-tv-shared/src/types/api/v1/schemas/auth/loginRequest.json';
import createUserSchema from 'miracle-tv-shared/src/types/api/v1/schemas/user/createUser.json';

import { Request } from 'server/lib/http/interfaces';
import { sendData, sendDuplicate, sendUnauthorized, sendNoContent } from 'server/lib/http/response';
import { checkPassword } from 'server/lib/crypto';

import { getSelf } from 'server/api/v1/handlers/users';

function login (req: Request, res: Response) {
Users.getV1UserByUsername(req.body.username)
.then((user) => {
@@ -59,5 +61,6 @@ const router = Router();
router.post('/login', acceptsSchema(loginSchema), login);
router.delete('/login', authenticateUser, logout);
router.post('/sign-up', acceptsSchema(createUserSchema), signUp);
router.get('/me', authenticateUser, getSelf);

export default router;

+ 1
- 1
src/server/api/v1/handlers/channels.ts Целия файл

@@ -10,7 +10,7 @@ import {
sendNoContent,
} from 'server/lib/http/response';

import createChannelJson from 'server/api/v1/schemas/channel/createChannel.json';
import createChannelJson from 'miracle-tv-shared/src/types/api/v1/schemas/channel/createChannel.json';
import { authenticateUser, acceptsSchema } from 'server/lib/http/middleware';
import { getIdFromParams } from 'server/lib/http/request';
import { isAdmin, isMod } from 'server/lib/crypto';


+ 2
- 2
src/server/api/v1/handlers/streamkeys.ts Целия файл

@@ -1,12 +1,13 @@
import { Router, Response } from 'express';

import IStreamKey from 'miracle-tv-shared/src/types/api/v1/interfaces/IStreamKey';

import { Request } from 'server/lib/http/interfaces';
import Streamkeys from 'server/db/Streamkeys';
import { getIdFromParams } from 'server/lib/http/request';
import { sendData, sendUnauthorized, sendNoContent } from 'server/lib/http/response';
import Channels from 'server/db/Channels';
import { authenticateUser } from 'server/lib/http/middleware';
import IStreamKey from '../interfaces/IStreamKey';

function getKeysByChannel (req: Request, res: Response) {
const id = getIdFromParams(req);
@@ -23,7 +24,6 @@ function getKeysByUser (req: Request, res: Response) {
}

function getKeysByMe (req: Request, res: Response) {
console.log(req.session);
Streamkeys
.getStreamKeysByCreatorId(req.session.user.id)
.then(sendData(res));


+ 7
- 3
src/server/api/v1/handlers/users.ts Целия файл

@@ -1,6 +1,8 @@
import { Response, Router } from 'express';

import IUser from 'server/api/v1/interfaces/IUser';
import IUser from 'miracle-tv-shared/src/types/api/v1/interfaces/IUser';
import * as createUserJson from 'miracle-tv-shared/src/types/api/v1/schemas/user/createUser.json';
import * as updateUserJson from 'miracle-tv-shared/src/types/api/v1/schemas/user/updateUser.json';

import { Request } from 'server/lib/http/interfaces';
import {
@@ -11,8 +13,6 @@ import {
sendUnauthorized,
} from 'server/lib/http/response';

import * as createUserJson from 'server/api/v1/schemas/user/createUser.json';
import * as updateUserJson from 'server/api/v1/schemas/user/updateUser.json';

import Users from 'server/db/Users';
import { acceptsSchema, authenticateUser, authorizeRoles } from 'server/lib/http/middleware';
@@ -63,6 +63,10 @@ export function del (req: Request, res: Response) {
}
}

export function getSelf(req: Request, res: Response) {
Users.getV1UserSafe(req.session.user.id).then(sendData(res));
}

const router = Router();

router.get('/', getList);



+ 0
- 21
src/server/api/v1/interfaces/IActivity.ts Целия файл

@@ -1,21 +0,0 @@
import { IUserSafe } from './IUser';
import { IWithTimestamps, IWithId } from 'server/lib/db/interfaces';

interface IActivityFields {
name: string;
verb: string;
created_by_id: string;
}

export interface IActivityRaw extends IWithTimestamps, IWithId, IActivityFields {}

interface IActivity extends IActivityRaw {
created_by: IUserSafe;
}

export interface IActivityForChannel extends IWithId {
name: string;
verb: string;
}

export default IActivity;

+ 0
- 17
src/server/api/v1/interfaces/IChannel.ts Целия файл

@@ -1,17 +0,0 @@
import { IUserSafe } from 'server/api/v1/interfaces/IUser';
import { IActivityForChannel } from './IActivity';

export interface IChannelRaw {
id?: string;
slug: string;
title: string;
description?: string;
created_by_id: string;
activity_id: string;
created_at?: Date;
updated_at?: Date;
}
export default interface IChannel extends IChannelRaw {
created_by: IUserSafe;
activity: IActivityForChannel;
}

+ 0
- 11
src/server/api/v1/interfaces/ISession.ts Целия файл

@@ -1,11 +0,0 @@
import IUser from 'server/api/v1/interfaces/IUser';

export default interface ISession {
id?: string;
user: IUser;
}

export interface ISessionRaw {
id?: string;
user_id: string;
}

+ 0
- 10
src/server/api/v1/interfaces/IStreamKey.ts Целия файл

@@ -1,10 +0,0 @@
import { IWithId, IWithTimestamps } from 'server/lib/db/interfaces';

interface IStreamKeyFields {
user_id: string;
channel_id: string;
created_by_id: string;
valid_for: number;
}

export default interface IStreamKey extends IStreamKeyFields, IWithId, IWithTimestamps {}

+ 0
- 26
src/server/api/v1/interfaces/IUser.ts Целия файл

@@ -1,26 +0,0 @@
interface ICommonUserFields {
id: string;
username: string;
bio?: string;
displayName: string;
singleChannelMode: boolean;
role: string;
}

export interface IUser extends ICommonUserFields {
email: string;
passwordHash: string;
passwordSalt: string;
}

export interface IUserSafe extends ICommonUserFields {
emailHash?: string;
}

export interface IUserCreation {
username: string;
email: string;
password: string;
}

export default IUser;


+ 0
- 9
src/server/api/v1/schemas/activity/createActivity.json Целия файл

@@ -1,9 +0,0 @@
{
"type": "object",
"properties": {
"name": { "type": "string" },
"verb": { "type": "string" }
},
"additionalProperties": false,
"required": [ "name" ]
}

+ 0
- 9
src/server/api/v1/schemas/auth/loginRequest.json Целия файл

@@ -1,9 +0,0 @@
{
"type": "object",
"properties": {
"username": { "type": "string" },
"password": { "type": "string", "minLength": 8 }
},
"additionalProperties": false,
"required": [ "username", "password" ]
}

+ 0
- 11
src/server/api/v1/schemas/channel/createChannel.json Целия файл

@@ -1,11 +0,0 @@
{
"type": "object",
"properties": {
"title": { "type": "string" },
"slug": { "type": "string" },
"description": { "type": "string" },
"activity_id": { "type": "string" }
},
"additionalProperties": false,
"required": [ "title", "slug", "activity_id" ]
}

+ 0
- 9
src/server/api/v1/schemas/streamkeys/createStreamkey.json Целия файл

@@ -1,9 +0,0 @@
{
"type": "object",
"properties": {
"user": { "type": "string" },
"channel": { "type": "string" }
},
"additionalProperties": false,
"required": [ "channel" ]
}

+ 0
- 10
src/server/api/v1/schemas/user/createUser.json Целия файл

@@ -1,10 +0,0 @@
{
"type": "object",
"properties": {
"username": { "type": "string" },
"email": { "type": "string" },
"password": { "type": "string", "minLength": 8 }
},
"additionalProperties": false,
"required": [ "username", "password", "email" ]
}

+ 0
- 9
src/server/api/v1/schemas/user/updateUser.json Целия файл

@@ -1,9 +0,0 @@
{
"type": "object",
"properties": {
"bio": { "type": "string" },
"displayName": { "type": "string" }
},
"minProperties": 1,
"additionalProperties": false
}


+ 4
- 3
src/server/db/Channels.ts Целия файл

@@ -1,12 +1,13 @@
import ramda from 'ramda';
import uuidv4 from 'uuid/v4';

import IChannel, { IChannelRaw } from 'miracle-tv-shared/src/types/api/v1/interfaces/IChannel';
import { IUserSafe } from 'miracle-tv-shared/src/types/api/v1/interfaces/IUser';
import { IActivityForChannel } from 'miracle-tv-shared/src/types/api/v1/interfaces/IActivity';

import db from 'server/db';
import IChannel, { IChannelRaw } from 'server/api/v1/interfaces/IChannel';
import Users from './Users';
import Activities from './Activities';
import { IUserSafe } from 'server/api/v1/interfaces/IUser';
import IActivity, { IActivityForChannel } from 'server/api/v1/interfaces/IActivity';

class Channels {



+ 1
- 3
src/server/db/Sessions.ts Целия файл

@@ -2,9 +2,7 @@ import uuidv4 from 'uuid/v4';

import db from 'server/db';

// import IUser, { IUserCreation, IUserSafe } from 'server/api/v1/interfaces/IUser';
import ISession, { ISessionRaw } from 'server/api/v1/interfaces/ISession';
import { hashPassword } from 'server/lib/crypto';
import ISession, { ISessionRaw } from 'miracle-tv-shared/src/types/api/v1/interfaces/ISession';

class Sessions {
augmentSession (rawSession?: ISessionRaw): PromiseLike<ISession|null> {


+ 1
- 1
src/server/db/Streamkeys.ts Целия файл

@@ -1,7 +1,7 @@
import uuidv4 from 'uuid/v4';

import db from 'server/db';
import IStreamKey from 'server/api/v1/interfaces/IStreamKey';
import IStreamKey from 'miracle-tv-shared/src/types/api/v1/interfaces/IStreamKey';

class Streamkeys {
getStreamKeysByChannelId =


+ 1
- 1
src/server/db/Users.ts Целия файл

@@ -4,7 +4,7 @@ import md5 from 'js-md5';

import db from 'server/db';

import IUser, { IUserCreation, IUserSafe } from 'server/api/v1/interfaces/IUser';
import IUser, { IUserCreation, IUserSafe } from 'miracle-tv-shared/src/types/api/v1/interfaces/IUser';
import { hashPassword } from 'server/lib/crypto';

export interface IUserSafeMap {



+ 2
- 2
src/server/lib/crypto.ts Целия файл

@@ -1,6 +1,6 @@
import * as crypto from 'crypto';
import IUser from 'server/api/v1/interfaces/IUser';
import { ADMIN_ROLE, USER_ROLE, MODERATOR_ROLE } from 'shared/lib/const';
import IUser from 'miracle-tv-shared/src/types/api/v1/interfaces/IUser';
import { ADMIN_ROLE, USER_ROLE, MODERATOR_ROLE } from 'miracle-tv-shared/src/lib/const';

interface IHashResult {
passwordHash: string;


+ 0
- 8
src/server/lib/db/interfaces.ts Целия файл

@@ -1,8 +0,0 @@
export interface IWithId {
id?: string;
}

export interface IWithTimestamps {
created_at?: Date;
updated_at?: Date;
}

+ 3
- 3
src/server/lib/http/interfaces.ts Целия файл

@@ -1,5 +1,5 @@
import { Request } from 'express';
import ISession from 'server/api/v1/interfaces/ISession';
import { Request as ERequest } from 'express';
import ISession from 'miracle-tv-shared/src/types/api/v1/interfaces/ISession';

export interface ErrorsObject {
[key: string]: string;
@@ -14,7 +14,7 @@ export interface ResponseObject<TData = any> {
message?: string;
}

export interface Request<T = any> extends Request {
export interface Request<T = any> extends ERequest {
session?: ISession;
body: T;
entity?: any;




+ 1
- 1
src/server/lib/http/response.ts Целия файл

@@ -1,7 +1,7 @@
import ramda from 'ramda';
import { Response } from 'express';

import { HTTP_CODES } from 'shared/lib/const';
import { HTTP_CODES } from 'miracle-tv-shared/src/lib/const';

export const sendData = ramda.curry((res: Response, data: any) => {
res.json({ data, status: 'ok' });


+ 2
- 6
src/server/lib/validation/errors.ts Целия файл

@@ -1,4 +1,4 @@
import { identity, uniq, last } from 'ramda';
import { identity, uniq } from 'ramda';

import {
ERROR_CODE_MISSING_PROPERTY,
@@ -6,7 +6,7 @@ import {
ERROR_CODE_TYPE,
ERROR_CODE_MAX_NUM, ERROR_CODE_MIN_NUM,
ERROR_CODE_MAX_STRING, ERROR_CODE_MIN_STRING,
} from 'shared/lib/const';
} from 'miracle-tv-shared/src/lib/const';

const propertyNameMap: { [key: string] : string } = {
required: 'missingProperty',
@@ -40,10 +40,6 @@ function commonErrorHandler (error: any) {
};
}

function defaultHandler (error: any) {
return error;
}

export function convertErrors (validationErrors: any): any {
const errorsByPath = validationErrors.reduce((acc: any, error: any) => {
const errorHandler = commonErrorHandler;



+ 8
- 3
src/server/server.ts Целия файл

@@ -1,9 +1,14 @@
import Express, { Request, Response } from 'express';

import Express from 'express';
import apiRouter from 'server/routes/api';
import db from 'server/db';

const app = Express();
export const appDB = db;

app.use('/api', apiRouter);

app.listen(8080, () => console.info('Listening on 8080!'));
export default app;

if (require.main === module) {
app.listen(8080, () => console.info('Listening on 8080!'));
}

+ 0
- 52
src/shared/lib/const.ts Целия файл

@@ -1,52 +0,0 @@
export const ERROR_CODE_MISSING_PROPERTY = 'errors.schema.field.missing';
export const ERROR_CODE_EXTRA_PROPERTY = 'errors.schema.field.noExtra';
export const ERROR_CODE_TYPE = 'errors.schema.field.type';
export const ERROR_CODE_MAX_NUM = 'errors.schema.field.maximumNumber';
export const ERROR_CODE_MIN_NUM = 'errors.schema.field.minimumNumber';
export const ERROR_CODE_MAX_STRING = 'errors.schema.field.maximumStringLength';
export const ERROR_CODE_MIN_STRING = 'errors.schema.field.minimumStringLength';

export const HTTP_CODE_OK = 200;
export const HTTP_CODE_CREATED = 201;
export const HTTP_CODE_NO_CONTENT = 204;
export const HTTP_CODE_BAD_REQUEST = 400;
export const HTTP_CODE_UNAUTHENTICATED = 401;
export const HTTP_CODE_UNAUTHORIZED = 403;
export const HTTP_CODE_NOT_FOUND = 404;
export const HTTP_CODE_SERVER_ERROR = 500;
export const HTTP_CODE_DUPLICATE = 409;
export const HTTP_CODE_NOT_IMPLEMENTED = 501;
export const HTTP_CODES = {
OK: HTTP_CODE_OK,
CREATED: HTTP_CODE_CREATED,
NO_CONTENT: HTTP_CODE_NO_CONTENT,
BAD_REQUEST: HTTP_CODE_BAD_REQUEST,
UNAUTHENTICATED: HTTP_CODE_UNAUTHENTICATED,
UNAUTHORIZED: HTTP_CODE_UNAUTHORIZED,
NOT_FOUND: HTTP_CODE_NOT_FOUND,
SERVER_ERROR: HTTP_CODE_SERVER_ERROR,
DUPLICATE: HTTP_CODE_DUPLICATE,
NOT_IMPLEMENTED: HTTP_CODE_NOT_IMPLEMENTED,
};

interface IRoleOption {
label: string;
value: string;
}

interface IRoleLabelMap {
[key: string]: string;
}

export const ADMIN_ROLE = 'admin';
export const MODERATOR_ROLE = 'mod';
export const USER_ROLE = 'user';
export const ROLE_OPTIONS: IRoleOption[] = [
{ label: 'Admin', value: ADMIN_ROLE },
{ label: 'Moderator', value: MODERATOR_ROLE },
{ label: 'User', value: USER_ROLE },
];

export const ROLE_LABEL_MAP: IRoleLabelMap = ROLE_OPTIONS
.reduce((acc: object, opt: IRoleOption) => ({ ...acc, [opt.value]: opt.label }), {});
export const ROLE_LIST: string[] = ROLE_OPTIONS.map(opt => opt.value);

+ 0
- 6
src/types/typings.d.ts Целия файл

@@ -1,6 +0,0 @@
declare module '*.json';
declare module 'server/db/knexfile';
declare module 'uuid/v4' {
function uuid4 (): string;
export = uuid4;
}


+ 3
- 1
test/server/lib/crypto.spec.ts Целия файл

@@ -21,7 +21,9 @@ describe('Cryptography password functions', () => {

it('checkPassword shouldn\'t match bad passwords', () => {
const resultObj = hashPassword(testPassword);
const checkResult = checkPassword(bogusPassword, resultObj.passwordHash, resultObj.passwordSalt);
const checkResult = checkPassword(
bogusPassword, resultObj.passwordHash, resultObj.passwordSalt,
);
expect(checkResult).to.be.false;
});
});



+ 1096
- 1226
yarn.lock
Файловите разлики са ограничени, защото са твърде много
Целия файл


Зареждане…
Отказ
Запис