index.js 11 KB

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