Update some stuff

This commit is contained in:
Amit Jakubowicz 2018-05-01 16:38:11 +02:00
parent ba9009fb6c
commit 922409758c
16 changed files with 57 additions and 224 deletions

4
.gitignore vendored
View file

@ -1,4 +1,6 @@
dist/
node_modules
.idea
yarn-error.log
yarn-error.log
.DS_Store
functions/lib

View file

@ -1,8 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.domain = 'quepasaalpujarra.com';
exports.mailgun = {
apiKey: 'key-64fc7260cecfd4a8d5fb51e97791b330',
domain: exports.domain
};
exports.projectId = 'calendar-189316';

View file

@ -1,24 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const url_1 = require("url");
const user_1 = require("./user");
exports.isUserAvailable = (req, res) => __awaiter(this, void 0, void 0, function* () {
const params = url_1.parse(req.url, true).query;
const user = yield user_1.getUser({
email: params.email,
username: params.username
});
console.log('got user from repository', JSON.stringify(user));
res.send({
exists: !!user
});
return true;
});

View file

@ -1,21 +0,0 @@
{
"name": "ts-gcf-functions",
"version": "1.0.0",
"main": "lib/index.js",
"license": "MIT",
"dependencies": {
"@google-cloud/datastore": "^1.4.0",
"mailgun-js": "^0.16.0",
"node-pre-gyp": "^0.9.0",
"randomstring": "^1.1.5"
},
"devDependencies": {
"@types/es6-promise": "^3.3.0",
"@types/node": "^9.6.1",
"tslint": "^5.9.1",
"typescript": "^2.8.1"
},
"scripts": {
"build": "./node_modules/.bin/tsc"
}
}

View file

@ -1,25 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const mailgun_js_1 = require("mailgun-js");
const config_1 = require("./config");
const client = mailgun_js_1.default(config_1.mailgun);
exports.sendEmail = (email) => __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
mailgun_js_1.default.messages().send(email, function (error, body) {
if (error) {
reject(error);
}
else {
resolve(body);
}
});
});
});

View file

@ -1,57 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const Datastore = require('@google-cloud/datastore');
const config_1 = require("./config");
const datastore = Datastore({
projectId: config_1.projectId,
});
class Repository {
static createUser(user) {
const entity = {
key: datastore.key('User'),
data: user
};
return datastore.save(entity);
}
static saveSessionInvite(invite) {
return __awaiter(this, void 0, void 0, function* () {
const entity = {
key: datastore.key('SessionInvite'),
data: invite
};
return yield datastore.save(entity);
});
}
static getUser(user) {
return __awaiter(this, void 0, void 0, function* () {
console.log('Search for user', JSON.stringify(user));
let query = datastore
.createQuery('user');
if (user.email) {
query = query.filter('email', '=', user.email);
}
if (user.username) {
query = query.filter('username', '=', user.username);
}
return yield datastore.runQuery(query)
.then(results => {
console.log('Got results', JSON.stringify(results));
const resultSet = results[0];
if (resultSet.length > 1) {
console.warn('Got more than one user, should have gotten at most one', JSON.stringify(resultSet));
}
return resultSet.length ? resultSet[0] : null;
});
});
}
;
}
exports.default = Repository;

View file

@ -1,46 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
// Free API to get location from IP: http://freegeoip.net/json/149.11.144.50
const randomstring_1 = require("randomstring");
const post_office_1 = require("./post_office");
const config_1 = require("./config");
const repository_1 = require("./repository");
const newInvite = (user) => {
return {
oneTimeKey: randomstring_1.default.generate({
length: 24,
charset: 'alphabetic'
}),
userId: user.id
};
};
exports.inviteUser = (user) => __awaiter(this, void 0, void 0, function* () {
const invite = newInvite(user);
try {
yield repository_1.default.saveSessionInvite(invite);
}
catch (e) {
console.error('Failed to save invite', invite);
throw e;
}
try {
yield post_office_1.sendEmail({
to: user.email,
from: `signin@${config_1.domain}`,
text: `invitation for session key: ${invite.oneTimeKey}`,
subject: 'Invitation for session'
});
}
catch (e) {
console.error('Failed to send invitation email', invite);
throw e;
}
});

View file

@ -1,14 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const repository_1 = require("./repository");
exports.getUser = (keys) => __awaiter(this, void 0, void 0, function* () {
return yield repository_1.default.getUser(keys);
});

View file

@ -5,9 +5,9 @@
"license": "MIT",
"dependencies": {
"@google-cloud/datastore": "^1.4.0",
"mailgun-js": "^0.16.0",
"mailgun-js": "^0.17.0",
"node-pre-gyp": "^0.9.0",
"randomstring": "^1.1.5"
"random-string": "^0.2.0"
},
"devDependencies": {
"@types/es6-promise": "^3.3.0",
@ -17,8 +17,7 @@
},
"scripts": {
"build": "./node_modules/.bin/tsc",
"deploy": "gcloud beta functions deploy isUserAvailable --trigger-http",
"deploy": "gcloud beta functions deploy signup --trigger-http",
"logs": "gcloud beta functions logs read"
}
}

View file

View file

@ -2,6 +2,7 @@ import {parse} from 'url'
import {getUser, createUser} from './user'
import { Request, Response } from 'express'
import { inviteUser } from './session'
import {UserProperties} from "./types";
export const isUserAvailable = async (req: Request, res: Response) => {
const params = parse(req.url, true).query
@ -20,7 +21,10 @@ export const isUserAvailable = async (req: Request, res: Response) => {
export const signup = async (req: Request, res: Response) => {
const {username, email, name} = req.body
console.log('Signup request', {username, email, name})
console.log('typeof req.body', typeof req.body)
console.log('req.body', req.body)
const userProperties: UserProperties = {username, email, name}
let newUser
try {
newUser = await createUser({
@ -38,7 +42,7 @@ export const signup = async (req: Request, res: Response) => {
inviteUser(newUser)
} else {
res.status(409)
res.send('Could not create user')
res.send(`Could not create user: ${JSON.stringify(userProperties)}`)
return
}
}

View file

@ -1,7 +1,6 @@
import mailgun from 'mailgun-js';
import {mailgun as mailgunConfig} from './config';
import { mailgun as mailgunConfig } from './config';
const client = mailgun(mailgunConfig);
const client = require('mailgun-js')(mailgunConfig);
interface Email {
from: string
@ -13,7 +12,7 @@ interface Email {
export const sendEmail = async (email: Email) => {
console.log('Will try to send following email', JSON.stringify(email))
return new Promise((resolve, reject) => {
mailgun.messages().send(email, function (error, body) {
client.messages().send(email, function (error, body) {
if (error) {
reject(error)
} else {

View file

@ -1,6 +1,6 @@
const Datastore = require('@google-cloud/datastore')
import {SessionInvite, User, UserKeys} from './types'
import { projectId } from './config'
import {SessionInvite, User, UserKeys, UserProperties} from './types'
import {projectId} from './config'
const datastore = Datastore({
projectId: projectId,
@ -8,12 +8,24 @@ const datastore = Datastore({
export default class Repository {
static createUser(user: User) {
async createUser(userProperties: UserProperties): Promise<User> {
const entity = {
key: datastore.key('User'),
data: user
key: datastore.key('user'),
data: userProperties
}
return datastore.save(entity)
return new Promise((resolve, reject) => {
return datastore.save(entity, err => {
if (err) {
reject(err)
} else {
const user = await this.getUser({
username: userProperties.username,
})
resolve(user as User)
}
})
})
}
static async saveSessionInvite(invite: SessionInvite) {
@ -24,7 +36,7 @@ export default class Repository {
return await datastore.save(entity)
}
static async getUser (user: UserKeys) {
static async getUser(user: UserKeys): Promise<User> {
let query = datastore
.createQuery('user')
@ -35,13 +47,19 @@ export default class Repository {
query = query.filter('username', '=', user.username)
}
return await datastore.runQuery(query)
.then(results => {
const resultSet = results[0]
if (resultSet.length > 1) {
console.warn('Got more than one user, should have gotten at most one', JSON.stringify(resultSet))
return new Promise((resolve, reject) => {
datastore.runQuery(query, (err, entities) => {
if (err) {
reject(err)
} else {
const resultSet = entities[0]
if (resultSet.length > 1) {
console.warn('Got more than one user, should have gotten at most one', JSON.stringify(resultSet))
}
const result: User = resultSet.length ? resultSet[0] : null
resolve(result)
}
return resultSet.length ? resultSet[0] : null
});
})
})
};
}

View file

@ -1,5 +1,5 @@
// Free API to get location from IP: http://freegeoip.net/json/149.11.144.50
import randomstring from 'randomstring'
import randomstring from 'random-string'
import { sendEmail } from './post_office'
import { domain } from './config'
@ -8,9 +8,10 @@ import {SessionInvite, User} from "./types";
const newInvite = (user: User): SessionInvite => {
return {
oneTimeKey: randomstring.generate({
oneTimeKey: randomstring({
length: 24,
charset: 'alphabetic'
letters: true,
special: false,
}),
userId: user.id
}

View file

@ -0,0 +1,5 @@
{
"name": "Amit Kapit",
"email": "jakubowicz.amit@gmail.com",
"username": "amitkapit"
}

View file

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es2015",
"target": "es6",
"module": "commonjs",
"outDir": "lib/"
},