Telegram auth (wip)

This commit is contained in:
vjrj 2018-01-26 12:49:53 +01:00
parent 5fe60d20d3
commit 58c54e5b94
7 changed files with 92 additions and 9 deletions

View file

@ -41,7 +41,7 @@ Meteor.publishTransformed('userSubsToFires', function transform() {
});
Meteor.publish('mysubscriptions', function subscriptions() {
return Subscriptions.find({ owner: this.userId, type: 'web' });
return Subscriptions.find({ owner: this.userId }); // type: 'web'
});
// Note: subscriptions.view is also used when editing an existing subscription.

View file

@ -1,6 +1,8 @@
/* eslint-disable import/no-absolute-path */
import { Meteor } from 'meteor/meteor';
import { check, Match } from 'meteor/check';
import { Accounts } from 'meteor/accounts-base';
import urlEnc from '/imports/modules/url-encode';
import editProfile from './edit-profile';
import rateLimit from '../../../modules/rate-limit';
@ -34,6 +36,13 @@ Meteor.methods({
'users.setLang': function userLang(lang) {
check(lang, validLangCode);
Meteor.users.update({ _id: this.userId }, { $set: { lang } });
},
'auth.getHash': async function getHash() {
const token = Accounts._generateStampedLoginToken();
const obj = Accounts._hashStampedToken(token);
// console.log(obj);
const sealed = await urlEnc.encrypt(obj);
return sealed;
}
});

View file

@ -292,6 +292,6 @@ export default translate([], { wait: true })(withTracker((props) => {
center: props.center[0] !== null ? props.center : geolocation.get(),
distance: props.distance,
loadingSubs: !subscription.ready(),
currentSubs: UserSubsToFiresCollection.find({ owner: Meteor.userId(), type: 'web' }).fetch()
currentSubs: UserSubsToFiresCollection.find({ owner: Meteor.userId() }).fetch() // type: 'web'
};
})(SelectionMap));

View file

@ -27,6 +27,7 @@ import NewSubscription from '../../pages/NewSubscription/NewSubscription';
import ViewSubscription from '../../pages/ViewSubscription/ViewSubscription';
import EditSubscription from '../../pages/EditSubscription/EditSubscription';
import Signup from '../../pages/Signup/Signup';
import Auth from '../../pages/Auth/Auth';
import Login from '../../pages/Login/Login';
import Logout from '../../pages/Logout/Logout';
import VerifyEmail from '../../pages/VerifyEmail/VerifyEmail';
@ -70,6 +71,7 @@ const App = props => (
<Authenticated exact path="/profile" component={Profile} {...props} />
<Route path="/fires" component={FiresMap} {...props} />
<Route path="/fire/:id" component={Fires} {...props} />
<Public path="/auth/:token" component={Auth} {...props} />
<Public path="/signup" component={Signup} {...props} />
<Public path="/login" component={Login} {...props} />
<Route path="/logout" component={Logout} {...props} />
@ -121,7 +123,7 @@ export default withTracker(() => {
const loading = !Roles.subscription.ready();
const name = user && user.profile && user.profile.name && getUserName(user.profile.name);
const emailAddress = user && user.emails && user.emails[0].address;
console.log(`i18n ready?: ${i18nReady.get()}`);
// console.log(`i18n ready?: ${i18nReady.get()}`);
return {
loading,
loggingIn,

View file

@ -0,0 +1,48 @@
/* eslint-disable react/jsx-indent-props */
/* eslint-disable import/no-absolute-path */
/* eslint-disable import/no-absolute-path */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { Bert } from 'meteor/themeteorchef:bert';
import { Meteor } from 'meteor/meteor';
import { T9n } from 'meteor-accounts-t9n';
import { Accounts } from 'meteor/accounts-base';
class Auth extends Component {
constructor(props) {
super(props);
const { token } = props.match.params;
// console.log(token);
console.log(Meteor.connection);
console.log(Accounts.connection);
Meteor.loginWithToken(token, (error) => {
// this is going to throw error if we logged out
if (error) {
Bert.alert(T9n.get(`error.accounts.${error.reason}`), 'danger');
// props.history.push('/login');
} else {
console.log('loginWithToken');
}
});
}
render() {
return (
<div />
);
}
}
Auth.propTypes = {
// t: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
match: PropTypes.object.isRequired
};
Auth.defaultProps = {
};
export default translate([], { wait: true })(Auth);

View file

@ -8,7 +8,6 @@ import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import randomHex from 'crypto-random-hex';
import Icon from '../../components/Icon/Icon';
import OAuthLoginButtons from '../../components/OAuthLoginButtons/OAuthLoginButtons';
import InputHint from '../../components/InputHint/InputHint';
@ -96,6 +95,26 @@ class Signup extends React.Component {
this.setState({ termsAccept });
}
onTelegramAuth() {
/* dynamic import sample
// https://github.com/meteor/meteor/issues/9038
import('crypto-random-hex').then(({ default: randomHex }) => {
// console.log(randomHex);
const hex = randomHex(20);
window.open(`https://t.me/TodosContraElFuego_bot?start=${hex}`);
}); */
Meteor.call('auth.getHash', (error, response) => {
if (error) {
console.warn(error);
} else {
const bot = Meteor.isDevelopment ? 'rednodetest_bot' : 'TodosContraElFuego_bot';
const url = `https://t.me/${bot}?start=${response}`;
// console.log(url);
window.open(url);
}
});
}
render() {
const { t, history } = this.props;
return (<div className="Signup">
@ -103,12 +122,12 @@ class Signup extends React.Component {
<Col xs={12} sm={6} md={5} lg={4}>
<h4 className="page-header">{t('Registrarse')}</h4>
<Row>
{ false && // disabled
{ Meteor.settings.public.telegramAuth &&
<Col xs={12}>
<button
className="btn btn-block btn-raised btn-primary OAuthLoginButtonDis OAuthLoginButton-telegram"
type="button"
onClick={() => { const hex = randomHex(20); console.log(hex); window.open(`https://t.me/TodosContraElFuego_bot?start=${hex}`); }}
onClick={this.onTelegramAuth}
>
<span><Icon icon="telegram" /> {t('Iniciar sesión con Telegram')}</span>
</button>

View file

@ -5,6 +5,7 @@
import { chai } from 'meteor/practicalmeteor:chai';
import ActiveFiresCollection from '/imports/api/ActiveFires/ActiveFires';
import urlEnc from '/imports/modules/url-encode';
import { Accounts } from 'meteor/accounts-base';
describe('url encoding', () => {
it('should encrypt and dcrypt basic objects', async () => {
@ -73,13 +74,17 @@ describe('url encoding', () => {
it('should decrypt node-red enc objects', async () => {
const sealed = 'Fe26.2**750f04110aef0f20d1093aa3f2a54dac3d7d5cc86e864e2c7d71b0ead88bc5b9*rX653dosl4BiM2L4fmZiiA*xuKj8XojCaS38R6X1EXkXBWjOidpnB0EVgGbdod_4vACHSl1w61hgXkU6SOq8HdURakJKCyIqWrsrdGt6DI6bl1xgfZ4ejlRMV_Keu0-WV0BVqrxbw0NlMN9KPexRDsy15yZou4ExU1yE36PBsfZIYysUrIsXwiBz3D5KvDaW0BnAXZ4sUR5Kyvk8g75QQmBth_LVHaEWE_OMarQUXDvFZ33R2_vM_i89QSj-wzwG5v-lbYrimE_5SMhEngRJFjihtQ_LfQlkH0wrpe5SUIdNL-DzsRxswvY7RIuMKHVLWSy8So66PxCuVJKa-DGvclX7tj7NO9RgNidfqP8U0izTpoV7dJB44Bwi4NOwLKGwNO9NG7jt-KGb2P6FeLTJYq8Mt0qqNsYXWUMpuhgXlKc2SuKT0avh-kYdovFO3YztGg5dz_Asu5hGZtkzRG6oGrvZxU8j7VDDNSQLLHo67Skmqg5_0e6Bp0gqpz13bmCSVvM_IpOkJLIgkRkGAvFoPy-woBqWiBU3NICo0z9X35WJ8j2xFY5niidGPXkP_uo5JbpGkmLH1tL06UUqjXZ5GS7gVhi8ii0vZt5zgaM4z0g4Q**96aa408156b0952f0d90e7c6d3960c06595543ffcfd642274138631b51b03383*BRnu9clkqVeKeXfWVe8i_Dh6TgqstVgV9HafoiLKxks';
const unsealed = await urlEnc.decrypt(sealed);
console.log(unsealed);
// console.log(unsealed);
});
it('should encrypt and dcrypt hashes', async () => {
const obj = '7e01bd8d25e8d1a7459a82d8dd8348594484641f';
it('should encrypt and dcrypt Accounts hashes', async () => {
const token = Accounts._generateStampedLoginToken();
const obj = Accounts._hashStampedToken(token);
console.log(obj);
const sealed = await urlEnc.encrypt(obj);
const unsealed = await urlEnc.decrypt(sealed);
const w = unsealed.when;
unsealed.when = new Date(w);
chai.expect(unsealed).to.deep.equal(obj);
});
});