index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. const ObjectID = require("mongodb").ObjectID;
  2. const jwt = require('jsonwebtoken')
  3. const jwtSecret = 'CbymrfGfnB'
  4. const anonResolvers = ['login', 'createUser'];
  5. ;(async () => {
  6. const {Savable, slice, getModels} = await require('./models.js')()
  7. class User extends Savable {
  8. static get relations(){
  9. return {
  10. }
  11. }
  12. }
  13. Savable.addClass(User)
  14. const express = require('express');
  15. const express_graphql = require('express-graphql');
  16. const { buildSchema } = require('graphql');
  17. const schema = buildSchema(`
  18. type Query {
  19. login(login: String!, password: String!): String
  20. categories: [Category]
  21. category(_id: ID!): Category
  22. goods: [Good]
  23. good(_id: ID!): Good
  24. myOrders: [Order]
  25. orders: [Order]
  26. }
  27. type Mutation {
  28. createUser(login: String!, password: String!): User
  29. changePassword(password: String!): User
  30. setCategory(cat: CategoryInput!):Category
  31. setGood(good: GoodInput!):Good
  32. setOrder(order: OrderInput):Order
  33. setOrderGood(orderGood: OrderGoodInput):OrderGood
  34. }
  35. type User {
  36. _id: String
  37. login: String
  38. nick : String
  39. orders: [Order]
  40. }
  41. type Category {
  42. _id: ID,
  43. name: String!,
  44. goods: [Good]
  45. }
  46. type Good {
  47. _id: ID,
  48. name: String!,
  49. description: String
  50. price: Float
  51. orderGoods: [OrderGood]
  52. categories: [Category]
  53. }
  54. type OrderGood {
  55. _id: ID,
  56. price: Float,
  57. count: Float,
  58. good: Good,
  59. order: Order
  60. total: Float
  61. }
  62. type Order {
  63. _id: ID
  64. orderGoods: [OrderGood]
  65. total: Float
  66. }
  67. input UserInput {
  68. _id: String
  69. login: String
  70. nick : String
  71. }
  72. input CategoryInput {
  73. _id: ID,
  74. name: String!,
  75. goods: [ID]
  76. }
  77. input GoodInput {
  78. _id: ID,
  79. name: String!,
  80. description: String
  81. price: Float
  82. categories: [ID]
  83. }
  84. input OrderGoodInput {
  85. _id: ID,
  86. count: Int!,
  87. good: ID!,
  88. order: ID!
  89. }
  90. input OrderInput {
  91. _id: ID
  92. orderGoods: [ID]
  93. }
  94. `);
  95. var app = express();
  96. app.use(express.static('public'));
  97. const rootResolvers = {
  98. createUser:async function ({login, password}){
  99. let user = await Savable.m.User.findOne({login, password})
  100. if (user)
  101. return null;
  102. user = await (new User({login, password})).save()
  103. user.___owner = user._id.toString()
  104. user.___permissions = {
  105. read: ["owner", "user"]
  106. }
  107. return await user.save()
  108. },
  109. login: async function({login, password}){
  110. console.log(Savable.classes)
  111. const user = await Savable.m.User.findOne({login, password})
  112. if (!user)
  113. return null;
  114. const token = jwt.sign({ sub: {id: user._id, login}}, jwtSecret); //подписывам токен нашим ключем
  115. return token
  116. },
  117. changePassword:async function ({password}, {jwt: {id}, models: {SlicedSavable, User}} ){
  118. id = new ObjectID(id)
  119. const user = await SlicedSavable.m.User.findOne({_id: id})
  120. if (!user)
  121. return null;
  122. user.password = password;
  123. return await user.save()
  124. },
  125. async setCategory({cat}, {jwt: {id}, models: {SlicedSavable, Category}}){
  126. if ('_id' in cat){
  127. let entity = await SlicedSavable.m.Category.findOne({_id: ObjectID(cat._id)})
  128. console.log(entity)
  129. if (entity){
  130. entity.name = cat.name
  131. if (cat.goods){
  132. entity.goods = []
  133. for (goodId of cat.goods){
  134. let good = await SlicedSavable.m.Good.findOne({_id: ObjectID(goodId)});
  135. good && entity.goods.push(good)
  136. }
  137. }
  138. return await entity.save()
  139. }
  140. }
  141. return await (new Category(cat)).save()
  142. },
  143. async categories({}, {jwt: {id}, models: {SlicedSavable, Category}}){
  144. categories = []
  145. for (let category of SlicedSavable.m.Category.find({})){
  146. try {category = await category} catch (e) { break }
  147. categories.push(category)
  148. }
  149. return categories;
  150. },
  151. async category({_id}, {jwt: {id}, models: {SlicedSavable, Category}}){
  152. return await SlicedSavable.m.Category.findOne({_id: ObjectID(_id)});
  153. },
  154. async setGood({good}, {jwt: {id}, models: {SlicedSavable, Good}}){
  155. if ('_id' in good){
  156. let entity = await SlicedSavable.m.Good.findOne({_id: ObjectID(good._id)})
  157. if (entity){
  158. entity.name = good.name
  159. entity.description = good.description
  160. entity.price = good.price
  161. if (good.categories){
  162. console.log(good.categories)
  163. entity.categories = []
  164. for (catId of good.categories){
  165. let cat = await SlicedSavable.m.Category.findOne({_id: ObjectID(catId)});
  166. cat && entity.categories.push(cat)
  167. }
  168. }
  169. return await entity.save()
  170. }
  171. }
  172. return await (new Good(good)).save()
  173. },
  174. async goods({}, {jwt: {id}, models: {SlicedSavable, Good}}){
  175. goods = []
  176. for (let good of SlicedSavable.m.Good.find({})){
  177. try {good = await good} catch (e) { break }
  178. goods.push(good)
  179. }
  180. return goods;
  181. },
  182. async good({_id}, {jwt: {id}, models: {SlicedSavable, Good}}){
  183. return await SlicedSavable.m.Good.findOne({_id: ObjectID(_id)});
  184. },
  185. async setOrder({order}, {jwt: {id}, models: {SlicedSavable, Order, thisUser}}){
  186. if ('_id' in order){
  187. let entity = await SlicedSavable.m.Order.findOne({_id: ObjectID(good._id)})
  188. if (entity){
  189. //entity.name = good.name
  190. //entity.description = good.description
  191. if (order.orderGoods){
  192. entity.orderGoods = []
  193. for (orderGoodId of entity.orderGoods){
  194. let orderGood = await SlicedSavable.m.OrderGood.findOne({_id: ObjectID(orderGoodId)});
  195. orderGood && entity.orderGoods.push(orderGood)
  196. }
  197. }
  198. entity.user = thisUser
  199. return await entity.save()
  200. }
  201. }
  202. order.user = thisUser
  203. return await (new Order(order)).save()
  204. },
  205. async orders({}, {jwt: {id}, models: {SlicedSavable}}){
  206. orders = []
  207. for (let order of SlicedSavable.m.Order.find({})){
  208. try {order = await order} catch (e) { break }
  209. orders.push(order)
  210. }
  211. return order;
  212. },
  213. async myOrders({}, {jwt: {id}, models: {SlicedSavable}}){
  214. orders = []
  215. for (let order of SlicedSavable.m.Order.find({___owner: id.toString(id)})){
  216. try {order = await order} catch (e) { break }
  217. orders.push(order)
  218. }
  219. return orders;
  220. },
  221. async order({_id}, {jwt: {id}, models: {SlicedSavable, Good}}){
  222. return await SlicedSavable.m.Order.findOne({_id: ObjectID(_id)});
  223. },
  224. async setOrderGood({orderGood}, {jwt: {id}, models: {SlicedSavable, OrderGood, thisUser}}){
  225. let order = await SlicedSavable.m.Order.findOne({'_id': ObjectID(orderGood.order)})
  226. let good = await SlicedSavable.m.Good.findOne ({'_id': ObjectID(orderGood.good)})
  227. if (order && good){
  228. let entity = await SlicedSavable.m.OrderGood.findOne({'order._id': order._id,
  229. 'good._id': good._id})
  230. if (!entity){
  231. console.log('wtf')
  232. entity = new OrderGood({})
  233. }
  234. entity.price = good.price
  235. entity.count = orderGood.count
  236. entity.order = order
  237. entity.good = good
  238. await entity.save()
  239. console.log(entity)
  240. return entity
  241. }
  242. return null;
  243. },
  244. }
  245. app.use('/graphql', express_graphql(async (req, res, gql) => {
  246. if (!gql.query){
  247. return {
  248. schema: schema,
  249. rootValue: rootResolvers,
  250. graphiql: true,
  251. }
  252. }
  253. const operationMatch = gql.query.match(/\{\s*([a-zA-Z]+)\s*/)
  254. const operationName = gql.operationName || operationMatch[1]
  255. console.log('before oper', operationName)
  256. if ((!operationName) || anonResolvers.includes(operationName)){
  257. return {
  258. schema: schema,
  259. rootValue: rootResolvers,
  260. graphiql: true,
  261. }
  262. }
  263. const authorization = req.headers.authorization
  264. console.log(authorization)
  265. if (authorization && authorization.startsWith('Bearer ')){
  266. console.log('token provided')
  267. const token = authorization.substr("Bearer ".length)
  268. const decoded = jwt.verify(token, jwtSecret)
  269. if (decoded){
  270. console.log('token verified', decoded)
  271. let slicedModels = await getModels(decoded.sub.id)
  272. return {
  273. schema: schema,
  274. rootValue: rootResolvers,
  275. graphiql: true,
  276. context: {jwt: decoded.sub,
  277. models: slicedModels}
  278. }
  279. }
  280. }
  281. console.log('bad end')
  282. }))
  283. app.listen(4000, () => console.log('Express GraphQL Server Now Running On localhost:4000/graphql'));
  284. })()