accounts-fake-server.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * @file
  3. * On the server side, an accounts package basically performs these tasks:
  4. *
  5. * - it exposes additional fields on Meteor.user() for autopublish
  6. * - it registers as a login handler with a given service name
  7. * - it publishes its runtime service configuration
  8. */
  9. const SERVICE_NAME = "fake";
  10. /**
  11. * Return the list of extra fields available on Meteor.user().
  12. *
  13. * This is invoked only if autopublish is enabled.
  14. *
  15. * @return {Object}
  16. * An object with up to two keys:
  17. * - forLoggedInUsers: an array of fields published to the current user
  18. * - forOtherUsers: an array of fields published to other users
  19. */
  20. function autopublishFields() {
  21. const allFields = "services." + SERVICE_NAME;
  22. const publicFields = allFields + ".public";
  23. return {
  24. forLoggedInUser: [allFields],
  25. forOtherUsers: [publicFields]
  26. };
  27. }
  28. /**
  29. * The fake login handler.
  30. *
  31. * @param {Object} loginRequest
  32. * The login request passed by Meteor. It will be of interest to the package
  33. * only if it contains a key named after the package.
  34. *
  35. * @return {Object} The result of a login request
  36. * - Undefined if the package does not handle this request.
  37. * - False if the package rejects the request.
  38. * - A result object containing the user information in case of login success.
  39. */
  40. function loginHandler(loginRequest) {
  41. let loginResult;
  42. // A login request goes through all these handlers to find its login handler.
  43. // So in our login handler, we only consider login requests which have an
  44. // field matching our service name, i.e. "fake". To avoid false positives,
  45. // any login package will only look for login request information under its
  46. // own service name, returning undefined otherwise.
  47. if (!loginRequest[SERVICE_NAME]) {
  48. return loginResult;
  49. }
  50. let options = loginRequest[SERVICE_NAME];
  51. // Never forget to check tainted data like these.
  52. // noinspection JSCheckFunctionSignatures
  53. check(options, {
  54. action: Boolean,
  55. user: String
  56. });
  57. // Use our ever-so-sophisticated authentication logic.
  58. if (!options.action) {
  59. loginResult = {
  60. type: SERVICE_NAME,
  61. error: new Meteor.Error("The login action said not to login.")
  62. };
  63. return loginResult;
  64. }
  65. // In case of success, ensure user account exists to find its id.
  66. let userName = options.user;
  67. let userCriteria = { username: userName };
  68. let userDocument = Meteor.users.findOne(userCriteria);
  69. let userId = userDocument
  70. ? userDocument._id
  71. : userName.toLocaleLowerCase();
  72. // Return a user
  73. let serviceData = {
  74. id: userId,
  75. extra: { some: "extra" }
  76. };
  77. // Publish part of the package-specific user information.
  78. let userOptions = {
  79. profile: serviceData.extra
  80. };
  81. return Accounts.updateOrCreateUserFromExternalService(SERVICE_NAME, serviceData, userOptions);
  82. }
  83. /**
  84. * Configure the service from its settings.
  85. *
  86. * Remember, this is a demo service which just demonstrates how to access both
  87. * public and private parts of configuration and expose them to client and
  88. * server.
  89. *
  90. * @return {void}
  91. */
  92. function configure() {
  93. let settings = Meteor.settings;
  94. let secret = settings[SERVICE_NAME].secret;
  95. let notSecret = settings.public[SERVICE_NAME]["not-secret"];
  96. if (typeof secret === "undefined" || secret !== notSecret) {
  97. throw new Meteor.ConfigError(SERVICE_NAME);
  98. }
  99. let serviceConfig = {
  100. service: SERVICE_NAME,
  101. secret: secret,
  102. notSecret: notSecret
  103. };
  104. // Unlike OAuth, we always reload the service configuration on application startup.
  105. let configurations = ServiceConfiguration.configurations;
  106. let selector = { service: SERVICE_NAME };
  107. configurations.upsert(selector, serviceConfig);
  108. }
  109. Meteor.startup(configure);
  110. Accounts.registerLoginHandler(SERVICE_NAME, loginHandler);
  111. Accounts.addAutopublishFields(autopublishFields());