Add package files to allow login with rocket.chat account

parent aa4326a7
# accounts-rocketchat
A login service for Rocket.Chat. See the [project page](https://www.meteor.com/accounts) on Meteor Accounts for more details.
Package.describe({
name: "rocketchat:accounts-rocketchat",
summary: "Login service for Rocket.Chat accounts",
version: "1.0.0"
});
Package.onUse(function (api) {
api.use(['underscore', 'random']);
api.use('oauth2', ['client', 'server']);
api.use('oauth', ['client', 'server']);
api.use('http', ['server']);
api.use(['underscore', 'service-configuration'], ['client', 'server']);
api.use(['random', 'templating'], 'client');
api.use('accounts-base', ['client', 'server']);
// Export Accounts (etc) to packages using this one.
api.imply('accounts-base', ['client', 'server']);
api.use('accounts-oauth', ['client', 'server']);
// api.export('RocketChat');
api.addFiles("rocketchat.js");
api.addFiles(['rocketchat_configure.html', 'rocketchat_configure.js', 'rocketchat-login-button.css'], 'client');
api.addFiles('rocketchat_server.js', 'server');
api.addFiles('rocketchat_client.js', 'client');
});
#login-buttons-image-rocketchat {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACG0lEQVR4AZWSA8xdQRSE76vdRrVt27ZtBrVt27YR1fbb/W3bto37Tuds7fYkXzKLmaU2dN4yTdZuZAAFWP8vbJ4FzoM7YD/oB4r9T8AKkAboE+miZoNzxoo1h7yvWGPSJwYYK9dqKGrUK/6rgCLgAiAYVYhVu64mx5Hjcl1nzNEB62zrDt2jMPbCWKX2TFmzQbkvAeoOajWcBQgTKeL6LUr38aO85GTSs7MVrNO9fSni2g3iYMx9KGo0qK8CsGolWafxK591myg7Jpb+UpgTQz5rNxI8L9mrYUtrXKbOzMtNTCRVJhPzR81z2QPvWg0X8yrs/CXi0nNyKPj4KQq/cl3p0LMXGNbcp8ZYc7GHvRzw8nNAfkYmeS5cRr6btkFnkPeqtQxr7lNjPIcrFB728hFWfXuEvJQUyk9L+6hTUxVc3MdjXBmxseQwYVqeqFJ7NV9iBTzPc//tu8iUm0t/qjxdp3j/AHJavAKX2OiZhFc9o7FSzVlOo8ZjtTTia0qIjKTogEBKiI5WxAQGUZC5BbkePkYWA4bliFoN78Fc5+NHqlGvKHZx2XvnHkrBNgOtrMhq2izdvO/gbIvR4/OBbt5/SJZs0zEcxieiap2p+AdlvnwkJK02a9k+3W7PPrLduoPMevZLRegpUbnWAFGp1lgwDvSRVWrXQ3+xX33labJuk1OyYfPrCNuNib2xQlEe/Be+iHeawaD0f/IBDCpL/jWYA9MAAAAASUVORK5CYII=);
}
Accounts.oauth.registerService("rocketchat");
if (Meteor.isClient) {
Meteor.loginWithRocketchat = function (options, callback) {
// support a callback without options
if (! callback && typeof options === "function") {
callback = options;
options = null;
}
var credentialRequestCompleteCallback = Accounts.oauth.credentialRequestCompleteHandler(callback);
RocketChat.requestCredential(options, credentialRequestCompleteCallback);
};
} else {
Accounts.addAutopublishFields({
// publish all fields including access token, which can legitimately be used
// from the client (if transmitted over ssl or on localhost).
forLoggedInUser: ['services.rocketchat'],
forOtherUsers: [
'services.rocketchat.id',
'services.rocketchat.username'
]
});
}
RocketChat = {};
// Request Rocket.Chat credentials for the user
//
// @param options {optional}
// @param credentialRequestCompleteCallback {Function} Callback function to call on
// completion. Takes one argument, credentialToken on success, or Error on
// error.
RocketChat.requestCredential = function (options, credentialRequestCompleteCallback) {
// support both (options, callback) and (callback).
if (!credentialRequestCompleteCallback && typeof options === 'function') {
credentialRequestCompleteCallback = options;
options = {};
}
var config = ServiceConfiguration.configurations.findOne({service: 'rocketchat'});
if (!config) {
credentialRequestCompleteCallback && credentialRequestCompleteCallback(
new ServiceConfiguration.ConfigError());
return;
}
if (!config.loginStyle) {
config.loginStyle = 'popup';
}
var credentialToken = Random.secret();
var loginStyle = OAuth._loginStyle('rocketchat', config, options);
var loginUrl =
config.server +
"/oauth/authorize?" +
"client_id=" + config.clientId +
"&state=" + OAuth._stateParam(loginStyle, credentialToken, options && options.redirectUrl) +
"&redirect_uri=" + OAuth._redirectUri('rocketchat', config);
launchLogin = {
loginService: "rocketchat",
loginStyle: loginStyle,
loginUrl: loginUrl,
credentialRequestCompleteCallback: credentialRequestCompleteCallback,
credentialToken: credentialToken,
popupOptions: {width: 620, height: 650}
};
OAuth.launchLogin(launchLogin);
};
<template name="configureLoginServiceDialogForRocketchat">
<p>
First, you'll need to get a Rocket.Chat account Client ID.
Follow these steps:
</p>
<ol>
<li> Go to your Rocket.Chat server administration</li>
<li> Click on OAuth Apps </li>
<li> Click "New application" and give your app a name</li>
<li> Add <span class="url">{{siteUrl}}_oauth/rocketchat</span> as Redirect URL. </li>
</ol>
</template>
Template.configureLoginServiceDialogForRocketchat.helpers({
siteUrl: function () {
return Meteor.absoluteUrl();
},
server: function() {
var config = ServiceConfiguration.configurations.findOne({service: 'rocketchat'});
return config && config.server;
}
});
Template.configureLoginServiceDialogForRocketchat.fields = function () {
return [
{property: 'clientId', label: 'App ID'},
{property: 'secret', label: 'App secret'},
{property: 'server', label: 'Server'}
];
};
RocketChat = {};
OAuth.registerService("rocketchat", 2, null, function (query) {
var response = getTokens(query);
var accessToken = response.accessToken;
var identity = getIdentity(accessToken);
var serviceData = {
accessToken: OAuth.sealSecret(accessToken),
expiresAt: (+new Date) + (1000 * response.expiresIn)
};
_.extend(serviceData, identity);
// only set the token in serviceData if it's there. this ensures
// that we don't lose old ones (since we only get this on the first
// log in attempt)
if (response.refreshToken)
serviceData.refreshToken = OAuth.sealSecret(response.refreshToken);
serviceData.id = serviceData._id;
return {
serviceData: serviceData,
options: {profile: {name: serviceData.username}}
// XXX use username for name until meteor accounts has a profile with a name
};
});
// returns an object containing:
// - accessToken
// - expiresIn: lifetime of token in seconds
// - refreshToken, if this is the first authorization request and we got a
// refresh token from the server
var getTokens = function (query) {
var config = ServiceConfiguration.configurations.findOne({
service: 'rocketchat'
});
if (!config)
throw new ServiceConfiguration.ConfigError();
var response;
try {
response = HTTP.post(
config.server + "/oauth/token", {
params: {
grant_type: "authorization_code",
code: query.code,
client_id: config.clientId,
client_secret: OAuth.openSecret(config.secret),
redirect_uri: OAuth._redirectUri('rocketchat', config)
}
}
);
} catch (err) {
throw _.extend(
new Error(
"Failed to complete OAuth handshake with Rocket.Chat. "
+ err.message
),
{response: err.response}
);
}
if (! response.data || response.data.error) {
// if the http response was a json object with an error attribute
throw new Error(
"Failed to complete OAuth handshake with Rocket.Chat. " +
(response.data ? response.data.error :
"No response data")
);
} else {
return {
accessToken: response.data.access_token,
refreshToken: response.data.refresh_token,
expiresIn: response.data.expires_in
};
}
};
var getIdentity = function (accessToken) {
var config = ServiceConfiguration.configurations.findOne({
service: 'rocketchat'
});
if (!config)
throw new ServiceConfiguration.ConfigError();
try {
return HTTP.get(
config.server + "/api/v1/me",
{
headers: { Authorization: "Bearer " + accessToken }
}
).data;
} catch (err) {
throw _.extend(new Error("Failed to fetch identity from Rocket.Chat. " + err.message), { response: err.response });
}
};
RocketChat.retrieveCredential = function (credentialToken, credentialSecret) {
return OAuth.retrieveCredential(credentialToken, credentialSecret);
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment