On the client:
EDIT: Looks like Meteor.userId()
is defined on page load when a resume login attempt will be made, which takes care of #1.
Here are a couple solutions:
Unfortunately by the time the stream handler is called with the result of the login method, Meteor.connection._methodInvokers
has been cleared – hence the search function. It would be nice if there was a different / more efficient way to know resumeMethodId
. A few possibilities:
"1"
?Meteor.connection._methodInvokers
were reactive, I could do an autorun that stops after the id is found..
resumeAttemptComplete = (success) ->
console.log 'resumeAttemptComplete', success
resumeMethodId = null
searchForResumeMethodId = ->
for id, invoker of Meteor.connection._methodInvokers
sentMessage = invoker._message
if sentMessage.method is 'login' and sentMessage.params[0].resume?
resumeMethodId = id
if Meteor.isClient
Meteor.connection._stream.on 'message', (messageString) ->
unless resumeMethodId
searchForResumeMethodId()
message = JSON.parse messageString
if message.id is resumeMethodId and message.msg is 'result'
resumeAttemptComplete !message.error
_methodInvokers
definition: https://github.com/meteor/meteor/blob/de74f2707ef34d1b9361784ecb4aa57803d34ae8/packages/ddp-client/livedata_connection.js#L79-L83
// server:
// map of connection ids -> publish function contexts
let onResumePublishers = {}
Meteor.publish('onResume', function () {
onResumePublishers[this.connection.id] = this
this.ready()
this.onStop(() => {
delete onResumePublishers[this.connection.id]
})
})
let handleLoginEvent = function({connection, type}, loggedIn) {
if (type === 'resume') {
let publisher = onResumePublishers[connection.id]
if (publisher)
publisher.added('onResume', connection.id, {loggedIn}})
}
}
Accounts.onLogin(function (loginAttempt) {
handleLoginEvent(loginAttempt, true)
})
Accounts.onLoginFailure(function (loginAttempt) {
handleLoginEvent(loginAttempt, false)
})
// client:
let resumeExpires = new Date(localStorage.getItem('Meteor.loginTokenExpires'))
let resumeAttemptBeingMade = resumeExpires && resumeExpires > new Date()
let OnResume = new Mongo.Collection('onResume')
let onResumeSubscription = Meteor.subscribe('onResume')
OnResume.find(Meteor.connection.id).observeChanges(
added(id, {loggedIn}) {
onResumeSubscription.stop()
onResumeAttemptCompleted(loggedIn)
}
})
let onResumeAttemptCompleted = function(success) {
// ...
}