User.coffee 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. class User extends Class
  2. constructor: ->
  3. @data = null
  4. @loading = false
  5. @inited = false # First load try done
  6. @loaded = new Promise()
  7. @loaded.then (res) =>
  8. @loading = false
  9. @log "Loaded", res
  10. Page.projector.scheduleRender()
  11. getInnerPath: ->
  12. return "data/users/#{Page.site_info.auth_address}/data.json"
  13. # Find new avalible index
  14. getNewIndex: (node) ->
  15. new_index = Date.now()
  16. for i in [0..100] # Find a free index
  17. if not @data[node][new_index+i]
  18. return new_index+i
  19. getDecryptedSecretsSent: (cb) ->
  20. if not @data?.secrets_sent
  21. cb false
  22. return false
  23. Page.cmd "eciesDecrypt", [@data.secrets_sent], (decrypted) =>
  24. if decrypted
  25. cb JSON.parse(decrypted)
  26. else
  27. cb false
  28. getPublickey: (user_address, cb) ->
  29. Page.cmd "fileGet", ["data/users/#{user_address}/data.json"], (res) =>
  30. data = JSON.parse(res)
  31. cb(data.publickey)
  32. addSecret: (secrets_sent, user_address, cb) ->
  33. @getPublickey user_address, (publickey) =>
  34. if not publickey
  35. cb false
  36. return Page.cmd "wrapperNotification", ["error", "No publickey for user #{user_address}"]
  37. Page.cmd "aesEncrypt", [""], (res) => # Generate new random AES key
  38. [key, iv, encrypted] = res
  39. Page.cmd "eciesEncrypt", [key, publickey], (secret) => # Encrypt the new key for remote user
  40. # Add for remote user
  41. @data.secret[@getNewIndex("secret")] = secret
  42. # Add key for me
  43. secrets_sent[user_address] = key
  44. Page.cmd "eciesEncrypt", [JSON.stringify(secrets_sent)], (secrets_sent_encrypted) =>
  45. if not secrets_sent_encrypted
  46. return cb false
  47. @data["secrets_sent"] = secrets_sent_encrypted
  48. cb key
  49. getSecret: (user_address, cb) ->
  50. @getDecryptedSecretsSent (secrets_sent) =>
  51. if not secrets_sent
  52. secrets_sent = {}
  53. if secrets_sent[user_address] # Already exits
  54. return cb(secrets_sent[user_address])
  55. else
  56. @log "Creating new secret for #{user_address}"
  57. @addSecret secrets_sent, user_address, (aes_key) ->
  58. cb aes_key
  59. loadData: (cb) ->
  60. inner_path = @getInnerPath()
  61. @log "Loading user file", inner_path
  62. Page.cmd "fileGet", {"inner_path": inner_path, "required": false}, (get_res) =>
  63. if get_res
  64. @data = JSON.parse(get_res)
  65. @loaded.resolve()
  66. if cb then cb(true)
  67. else
  68. if cb then cb(false)
  69. @inited = true
  70. createData: ->
  71. inner_path = @getInnerPath()
  72. @log "Creating user file", inner_path
  73. # First visit, no public key yet
  74. @data = {"secret": {}, "secrets_sent": "", "publickey": null, "message": {}, "date_added": Date.now()}
  75. Page.cmd "userPublickey", [], (publickey_res) =>
  76. if publickey_res.error
  77. Page.cmd "wrapperNotification", ["error", "Publickey read error: #{publickey_res.error}"]
  78. @loaded.fail()
  79. else
  80. @data.publickey = publickey_res
  81. @saveData().then (save_res) =>
  82. @loaded.resolve(save_res)
  83. saveData: (publish=true) ->
  84. promise = new Promise()
  85. inner_path = @getInnerPath()
  86. Page.cmd "fileWrite", [inner_path, Text.fileEncode(@data)], (write_res) =>
  87. if write_res != "ok"
  88. Page.cmd "wrapperNotification", ["error", "File write error: #{write_res}"]
  89. promise.fail()
  90. return false
  91. Page.cmd "sitePublish", {"inner_path": inner_path}, (publish_res) =>
  92. if publish_res == "ok"
  93. Page.message_lists.sent.reload = true
  94. Page.projector.scheduleRender()
  95. promise.resolve()
  96. else
  97. promise.resolve()
  98. return promise
  99. onSiteInfo: (site_info) ->
  100. if not @loading and site_info.event and site_info.event[0] == "file_done" and site_info.event[1] == @getInnerPath() # User file downloaded
  101. @loadData()
  102. if not @data and not @loading and site_info.cert_user_id and (not site_info.event or site_info.event?[0] == "cert_changed") # Startup or changed user
  103. @loadData()
  104. if not site_info.cert_user_id # Logged out
  105. @data = null
  106. window.User = User