rename tokens to loginTokens

master
Peter Babič 5 years ago
parent b3128ede9a
commit 27778a8360
Signed by: peter.babic
GPG Key ID: 4BB075BC1884BA40
  1. 91
      package-lock.json
  2. 4
      package.json
  3. 9
      src/app.ts
  4. 28
      src/app/UserResolver.spec.ts
  5. 8
      src/app/UserResolver.ts
  6. 24
      src/app/schema.ts
  7. 2
      src/app/userResolver/LoginTokens.ts
  8. 6
      src/app/userResolver/auth.ts

91
package-lock.json generated

@ -560,16 +560,6 @@
"@types/serve-static": "*" "@types/serve-static": "*"
} }
}, },
"@types/express-jwt": {
"version": "0.0.42",
"resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz",
"integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/express-unless": "*"
}
},
"@types/express-serve-static-core": { "@types/express-serve-static-core": {
"version": "4.16.9", "version": "4.16.9",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.9.tgz", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.9.tgz",
@ -579,15 +569,6 @@
"@types/range-parser": "*" "@types/range-parser": "*"
} }
}, },
"@types/express-unless": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz",
"integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==",
"dev": true,
"requires": {
"@types/express": "*"
}
},
"@types/fs-capacitor": { "@types/fs-capacitor": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz",
@ -732,6 +713,15 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz",
"integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==" "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w=="
}, },
"@types/node-fetch": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.2.tgz",
"integrity": "sha512-djYYKmdNRSBtL1x4CiE9UJb9yZhwtI1VC+UxZD0psNznrUj80ywsxKlEGAE+QL1qvLjPbfb24VosjkYM6W4RSQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/range-parser": { "@types/range-parser": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
@ -1216,11 +1206,6 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true "dev": true
}, },
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
},
"async-limiter": { "async-limiter": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
@ -2146,6 +2131,15 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
}, },
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"dev": true,
"requires": {
"iconv-lite": "~0.4.13"
}
},
"end-of-stream": { "end-of-stream": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@ -2360,22 +2354,6 @@
} }
} }
}, },
"express-jwt": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz",
"integrity": "sha512-1C9RNq0wMp/JvsH/qZMlg3SIPvKu14YkZ4YYv7gJQ1Vq+Dv8LH9tLKenS5vMNth45gTlEUGx+ycp9IHIlaHP/g==",
"requires": {
"async": "^1.5.0",
"express-unless": "^0.3.0",
"jsonwebtoken": "^8.1.0",
"lodash.set": "^4.0.0"
}
},
"express-unless": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz",
"integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA="
},
"extend": { "extend": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@ -3719,6 +3697,28 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true "dev": true
}, },
"isomorphic-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"dev": true,
"requires": {
"node-fetch": "^1.0.1",
"whatwg-fetch": ">=0.10.0"
},
"dependencies": {
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"dev": true,
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
}
}
}
},
"isstream": { "isstream": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -4535,11 +4535,6 @@
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
}, },
"lodash.set": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
"integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
},
"lodash.sortby": { "lodash.sortby": {
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@ -6903,6 +6898,12 @@
"iconv-lite": "0.4.24" "iconv-lite": "0.4.24"
} }
}, },
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==",
"dev": true
},
"whatwg-mimetype": { "whatwg-mimetype": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",

@ -5,7 +5,8 @@
"main": "src/app.js", "main": "src/app.js",
"scripts": { "scripts": {
"dev": "ts-node-dev --respawn src/app.ts", "dev": "ts-node-dev --respawn src/app.ts",
"test": "jest -i --coverage", "test": "jest --coverage",
"test:debug": "jest -i --verbose --detectOpenHandles",
"test:watch": "jest -i --watch", "test:watch": "jest -i --watch",
"gen:key": "ssh-keygen -t rsa -b 2048 -f src/app/userResolver/auth/jwtRS256.key && openssl rsa -in src/app/userResolver/auth/wtRS256.key -pubout -outform PEM -out src/app/userResolver/auth/wtRS256.key.pub" "gen:key": "ssh-keygen -t rsa -b 2048 -f src/app/userResolver/auth/jwtRS256.key && openssl rsa -in src/app/userResolver/auth/wtRS256.key -pubout -outform PEM -out src/app/userResolver/auth/wtRS256.key.pub"
}, },
@ -29,7 +30,6 @@
"@types/express": "^4.17.1", "@types/express": "^4.17.1",
"@types/graphql": "^14.5.0", "@types/graphql": "^14.5.0",
"@types/jest": "^24.0.18", "@types/jest": "^24.0.18",
"@types/js-cookie": "^2.2.2",
"@types/jsonwebtoken": "^8.3.3", "@types/jsonwebtoken": "^8.3.3",
"@types/node": "^12.7.5", "@types/node": "^12.7.5",
"class-transformer": "^0.2.3", "class-transformer": "^0.2.3",

@ -1,10 +1,10 @@
require("dotenv").config() require("dotenv").config()
import { ApolloServer } from "apollo-server-express" import { ApolloServer } from "apollo-server-express"
import { createConnection } from "typeorm" import { createConnection } from "typeorm"
import { connectionOptions, createSchema } from "./app/schema" import { connectionOptionsforDB, createSchema } from "./app/schema"
import express = require("express") import express = require("express")
;(async () => { ;(async () => {
await createConnection(connectionOptions) await createConnection(connectionOptionsforDB())
const server = new ApolloServer({ const server = new ApolloServer({
schema: await createSchema(), schema: await createSchema(),
@ -17,10 +17,9 @@ import express = require("express")
const app = express() const app = express()
server.applyMiddleware({ app }) server.applyMiddleware({ app })
const APP_PORT = process.env.APP_PORT || 4000 app.listen({ port: process.env.APP_PORT }, () =>
app.listen({ port: APP_PORT }, () =>
console.log( console.log(
`🚀 Server ready at http://localhost:${APP_PORT}${server.graphqlPath}. ` `Server ready at http://localhost:${process.env.APP_PORT}${server.graphqlPath}`
) )
) )
})() })()

@ -1,12 +1,12 @@
import { gql } from "apollo-server" import { gql } from "apollo-server"
import { createConnection, getConnection } from "typeorm" import { createConnection, getConnection } from "typeorm"
import { callSchema, connectionOptions } from "./schema" import { callSchema, connectionOptionsforDB } from "./schema"
import { signToken, verifyToken } from "./userResolver/auth" import { signToken, verifyToken } from "./userResolver/auth"
import { Tokens } from "./userResolver/Tokens" import { LoginTokens } from "./userResolver/LoginTokens"
import { User } from "./userResolver/User" import { User } from "./userResolver/User"
beforeAll(async () => { beforeAll(async () => {
return await createConnection(connectionOptions) return await createConnection(connectionOptionsforDB("testing"))
}) })
afterAll(async () => { afterAll(async () => {
@ -60,17 +60,17 @@ describe("resolver of user", () => {
}) })
}) })
describe("tokens query should", () => { describe("loginTokens query should", () => {
const tokensQuery = gql` const loginTokensQuery = gql`
query { query {
tokens(email: "email@email.com", password: "good-password") { loginTokens(email: "email@email.com", password: "good-password") {
accessToken accessToken
} }
} }
` `
it("return error for non-existent user", async () => { it("return error for non-existent user", async () => {
const response = await callSchema(tokensQuery) const response = await callSchema(loginTokensQuery)
expect(response.errors).not.toBeUndefined() expect(response.errors).not.toBeUndefined()
expect(response.data).toBeNull() expect(response.data).toBeNull()
@ -82,7 +82,7 @@ describe("resolver of user", () => {
password: "BAD-password", password: "BAD-password",
}).save() }).save()
const response = await callSchema(tokensQuery) const response = await callSchema(loginTokensQuery)
expect(response.errors).not.toBeUndefined() expect(response.errors).not.toBeUndefined()
expect(response.data).toBeNull() expect(response.data).toBeNull()
@ -94,14 +94,14 @@ describe("resolver of user", () => {
password: "good-password", password: "good-password",
}).save() }).save()
const response = await callSchema(tokensQuery) const response = await callSchema(loginTokensQuery)
const token = response.data!.tokens.accessToken const accessToken = response.data!.loginTokens.accessToken
const tokens = new Tokens() const loginTokens = new LoginTokens()
tokens.accessToken = token loginTokens.accessToken = accessToken
expect(response.errors).toBeUndefined() expect(response.errors).toBeUndefined()
expect(response.data).toMatchObject({ tokens }) expect(response.data).toMatchObject({ loginTokens })
expect(verifyToken(token)).toBeTruthy() expect(verifyToken(accessToken)).toBeTruthy()
}) })
}) })

@ -1,7 +1,7 @@
import "reflect-metadata" import "reflect-metadata"
import { Arg, Authorized, Ctx, Mutation, Query } from "type-graphql" import { Arg, Authorized, Ctx, Mutation, Query } from "type-graphql"
import { comparePassword, MyContext, signToken } from "./userResolver/auth" import { comparePassword, MyContext, signToken } from "./userResolver/auth"
import { Tokens } from "./userResolver/Tokens" import { LoginTokens } from "./userResolver/LoginTokens"
import { User } from "./userResolver/User" import { User } from "./userResolver/User"
export class UserResolver { export class UserResolver {
@ -10,11 +10,11 @@ export class UserResolver {
return await User.find() return await User.find()
} }
@Query(() => Tokens) @Query(() => LoginTokens)
async tokens( async loginTokens(
@Arg("email") email: string, @Arg("email") email: string,
@Arg("password") password: string @Arg("password") password: string
): Promise<Tokens> { ): Promise<LoginTokens> {
try { try {
const user = await User.findOne({ where: { email } }) const user = await User.findOne({ where: { email } })

@ -26,14 +26,18 @@ export const createSchema = () =>
authChecker: customAuthChecker, authChecker: customAuthChecker,
}) })
export const connectionOptions: ConnectionOptions = { export const connectionOptionsforDB = (dbName?: string) => {
type: "postgres", let connectionOptions: ConnectionOptions = {
host: process.env.DB_HOST, type: "postgres",
port: 5432, host: process.env.DB_HOST,
database: process.env.DB_NAME, port: 5432,
username: process.env.DB_USER, database: dbName || process.env.DB_NAME,
password: process.env.DB_PASS, username: process.env.DB_USER,
entities: [User], password: process.env.DB_PASS,
synchronize: true, entities: [User],
logging: false, synchronize: true,
logging: false,
}
return connectionOptions
} }

@ -2,7 +2,7 @@ import "reflect-metadata"
import { Field, ObjectType } from "type-graphql" import { Field, ObjectType } from "type-graphql"
@ObjectType() @ObjectType()
export class Tokens { export class LoginTokens {
@Field() @Field()
accessToken: string = "" accessToken: string = ""
} }

@ -43,13 +43,13 @@ export const verifyToken = (token: string) => {
export const customAuthChecker: AuthChecker<MyContext> = ({ context }) => { export const customAuthChecker: AuthChecker<MyContext> = ({ context }) => {
try { try {
const authHeader = context.req.headers["authorization"] const authHeader = context.req.headers["authorization"]
const token = authHeader!.split(" ")[1] const accessToken = authHeader!.split(" ")[1]
const payload = verifyToken(token) const payload = verifyToken(accessToken)
context.payload = payload as any context.payload = payload as any
return true return true
} catch (error) { } catch (error) {
throw new Error("the valid authorization header is required") throw new Error("the valid authorization header is required: ")
} }
} }

Loading…
Cancel
Save