Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/hub/api/handler.coffee
Views: 687
#########################################################################1# This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2# License: MS-RSL – see LICENSE.md for details3#########################################################################45###6API for handling the messages described packages/util/message.js78MS-RSL, (c) 2017, SageMath, Inc.9###1011async = require('async')1213{getAccountWithApiKey} = require("@cocalc/server/api/manage");1415Cache = require('lru-cache')16auth_cache = new Cache(max:100, ttl:60000)1718misc = require('@cocalc/util/misc')19{defaults, required} = misc2021messages = require('@cocalc/util/message')2223{ HELP_EMAIL } = require("@cocalc/util/theme")2425{Client} = require('../client')2627log = (name, logger) ->28return (m) -> logger.debug("API.#{name}: #{m}")2930exports.http_message_api_v1 = (opts) ->31try32opts = defaults opts,33event : required34body : required35api_key : required36database : required37projectControl : required38ip_address : required39logger : required40cb : required41catch err42opts.cb(err)43return44dbg = log('http_message_api_v1', opts.logger)45dbg("event=#{JSON.stringify(opts.event)}, body=#{JSON.stringify(opts.body)}")4647f = messages[opts.event]48if not f?49opts.cb("unknown endpoint '#{opts.event}'")50return5152if not messages.api_messages[opts.event]53opts.cb("endpoint '#{opts.event}' is not part of the HTTP API")54return5556try57mesg = f(opts.body, true)58catch err59opts.cb("invalid parameters '#{err}'")60return6162if mesg.event == 'query' and mesg.multi_response63otps.cb("multi_response queries aren't supported")64return6566# client often expects id to be defined.67mesg.id ?= misc.uuid()6869client = resp = undefined70async.series([71(cb) ->72get_client73api_key : opts.api_key74logger : opts.logger75database : opts.database76projectControl : opts.projectControl77ip_address : opts.ip_address78cb : (err, c) ->79client = c; cb(err)80(cb) ->81handle_message82client : client83mesg : mesg84logger : opts.logger85cb : (err, r) ->86resp = r; cb(err)87], (err) ->88if err89dbg("#{err} - #{JSON.stringify(resp)}")90opts.cb(err, resp)91)9293get_client = (opts) ->94opts = defaults opts,95api_key : required96logger : required97database : required98projectControl : required99ip_address : required100cb : required101dbg = log('get_client', opts.logger)102dbg()103104account_id = auth_cache.get(opts.api_key)105106async.series([107(cb) ->108if account_id109cb()110else111try112account_id = await getAccountWithApiKey(opts.api_key)113if not account_id?114cb("No account found. Is your API key wrong?")115return116# briefly cache api key. see "expire" time in ms above.117auth_cache.set(opts.api_key, account_id)118cb()119catch err120cb(err)121return122(cb) ->123# check if user is banned:124opts.database.is_banned_user125account_id : account_id126cb : (err, is_banned) ->127if err128cb(err)129return130if is_banned131cb("User is BANNED. If this is a mistake, please contact #{HELP_EMAIL}")132return133cb()134135], (err) ->136if err137opts.cb(err)138return139options =140logger : opts.logger141database : opts.database142projectControl : opts.projectControl143client = new Client(options)144client.push_to_client = (mesg, cb) =>145client.emit('push_to_client', mesg)146cb?()147client.ip_address = opts.ip_address148client.account_id = account_id149opts.cb(undefined, client)150)151152handle_message = (opts) ->153opts = defaults opts,154mesg : required155client : required156logger : undefined157cb : required158dbg = log('handle_message', opts.logger)159dbg("#{JSON.stringify(opts.mesg)}, #{opts.client.id}")160name = "mesg_#{opts.mesg.event}"161f = opts.client[name]162if not f?163opts.cb("unknown message event type '#{opts.mesg.event}'")164return165opts.client.once 'push_to_client', (mesg) ->166opts.cb(undefined, mesg)167f(opts.mesg)168169170171172173