From 101acac9a3818f94ed8401da0e99e18e14230b60 Mon Sep 17 00:00:00 2001 From: Nick Martin Date: Wed, 26 Sep 2012 19:51:01 -0700 Subject: [PATCH] Meteor.user() on the server (only in methods for now). --- packages/accounts-base/accounts_client.js | 6 +++- packages/accounts-base/accounts_server.js | 26 ++++++++++++++++ packages/accounts-password/passwords_tests.js | 31 ++++++++++++++++++- .../passwords_tests_setup.js | 7 +++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/packages/accounts-base/accounts_client.js b/packages/accounts-base/accounts_client.js index fa7854b9e2..4d8c6c02d2 100644 --- a/packages/accounts-base/accounts_client.js +++ b/packages/accounts-base/accounts_client.js @@ -1,7 +1,11 @@ (function () { + Meteor.userId = function () { + return Meteor.default_connection.userId(); + }; + Meteor.user = function () { - var userId = Meteor.default_connection.userId(); + var userId = Meteor.userId(); if (userId) { var result = Meteor.users.findOne(userId); if (result) { diff --git a/packages/accounts-base/accounts_server.js b/packages/accounts-base/accounts_server.js index f6519fefd3..5215f338b6 100644 --- a/packages/accounts-base/accounts_server.js +++ b/packages/accounts-base/accounts_server.js @@ -73,6 +73,32 @@ }); + /// + /// CURRENT USER + /// + Meteor.userId = function () { + // This function only works if called inside a method. In theory, it + // could also be called from publish statements, since they also + // have a userId associated with them. However, given that publish + // functions aren't reactive, using any of the infomation from + // Meteor.user() in a publish function will always use the value + // from when the function first runs. This is likely not what the + // user expects. The way to make this work in a publish is to do + // Meteor.find(this.userId()).observe and recompute when the user + // record changes. + var currentInvocation = Meteor._CurrentInvocation.get(); + if (!currentInvocation || !currentInvocation.userId) + throw new Error("Meteor.userId can only be invoked in method calls."); + return currentInvocation.userId(); + }; + + Meteor.user = function () { + var userId = Meteor.userId(); + if (!userId) + return null; + return Meteor.users.findOne(userId); + }; + /// /// CREATE USER HOOKS /// diff --git a/packages/accounts-password/passwords_tests.js b/packages/accounts-password/passwords_tests.js index 9c09920905..ee8757157d 100644 --- a/packages/accounts-password/passwords_tests.js +++ b/packages/accounts-password/passwords_tests.js @@ -165,7 +165,28 @@ if (Meteor.isClient) (function () { test.equal(Meteor.user().profile.touchedByOnCreateUser, true); })); }, - logoutStep + + // test Meteor.user(). This test properly belongs in + // accounts-base/accounts_tests.js, but this is where the tests that + // actually log in are. + function(test, expect) { + var clientUser = Meteor.user(); + Meteor.call('testMeteorUser', expect(function (err, result) { + test.equal(result._id, clientUser._id); + test.equal(result.profile.touchedByOnCreateUser, true); + test.equal(err, undefined); + })); + }, + logoutStep, + function(test, expect) { + var clientUser = Meteor.user(); + test.equal(clientUser, null); + Meteor.call('testMeteorUser', expect(function (err, result) { + test.equal(err, undefined); + test.equal(result, null); + })); + } + ]); }) (); @@ -234,6 +255,14 @@ if (Meteor.isServer) (function () { }); + // This test properly belongs in accounts-base/accounts_tests.js, but + // this is where the tests that actually log in are. + Tinytest.add('accounts - user() out of context', function (test) { + // basic server context, no method. + test.throws(function () { + Meteor.user(); + }); + }); // XXX would be nice to test Meteor.accounts.config({forbidSignups: true}) }) (); diff --git a/packages/accounts-password/passwords_tests_setup.js b/packages/accounts-password/passwords_tests_setup.js index 06831bacfc..5ffeae38a6 100644 --- a/packages/accounts-password/passwords_tests_setup.js +++ b/packages/accounts-password/passwords_tests_setup.js @@ -32,3 +32,10 @@ Meteor.accounts.config({ requireEmail: false, requireUsername: false }); + + +// This test properly belongs in accounts-base/accounts_tests.js, but +// this is where the tests that actually log in are. +Meteor.methods({ + testMeteorUser: function () { return Meteor.user(); } +});