diff --git a/README.md b/README.md
index 9e0b738d..010f7b28 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,14 @@
-# databases
+# Learn Databases
-Fork the repository
-Go to https://c0d3.com
-Create a username and account
+A free site to learn and try different databases.
-Ssh into c0d3 server
-`ssh [c0d3.com username]@c0d.com -p 221`
+**Installation**
-Clone your fork on the server
-`git clone https://github.com/[github username]/databases.git`
-
-To run server
-1. install nodemon
-2. run npm start:dev
-
-To install nodemon
-`npm i -g nodemon`
-
-To start the server
-`npm run start:dev`
-
-If you need to make changes to the Database run:
-`ALTER_DB=true npm run start:dev`
+1. Fork the repository. If you're new to github refer to this [guide](https://github.com/garageScript/curriculum/wiki/Engineering-Workflow).
+2. Download the fork into your local machine.
+3. Install required node modules with `npm i`.
+4. Create new .env file, it should look like env.example but with valid credentials instead of `***`. Ask for passwords and api keys on our [chat](https://chat.c0d3.com/c0d3/channels/).
+5. Start server with `npm run start:dev` and register a new user.
### Production Phases
@@ -34,13 +21,9 @@ Phase 3: API to power user interactions (backend)
Phase 4: UI (aka frontend)
**We are here!**
-What needs to worked on
-https://github.com/garageScript/databases/issues
+* [Issues](https://github.com/garageScript/databases/issues)
-Wiki
-https://github.com/garageScript/databases/wiki
+* [Wiki](https://github.com/garageScript/databases/wiki)
-If you have any questions message us on our chat:
-https://chat.c0d3.com/c0d3/channels/
+* If you have any questions message us on our [chat](https://chat.c0d3.com/c0d3/channels/)
-__Sequelize credentials are in the chat for privacy__
diff --git a/database/elasticsearch/elastic.js b/database/elasticsearch/elastic.js
index 7d808138..a41d5bbd 100644
--- a/database/elasticsearch/elastic.js
+++ b/database/elasticsearch/elastic.js
@@ -24,7 +24,7 @@ const sendESRequest = (path, method, body) => {
};
es.createAccount = async (account) => {
- if (!account.username || !account.dbPassword || !account.email) {
+ if (!account.username || !account.dbPassword) {
logger.error("Account data is invalid");
throw new Error("Account data is invalid");
}
@@ -87,10 +87,10 @@ es.deleteAccount = async (account) => {
if (err || !r1.found || !r2.found) {
logger.error("Deleting Elasticsearch user failed");
throw new Error(
- `Failed to delete Elasticsearch account for user: ${account.email}`
+ `Failed to delete Elasticsearch account for user: ${account.id}`
);
}
- logger.info("Successfully deleted Elasticsearch user", account.email);
+ logger.info("Successfully deleted Elasticsearch user", account.id);
};
es.checkAccount = async (account) => {
diff --git a/database/postgres/pg.js b/database/postgres/pg.js
index 8c5a5278..221db7e3 100644
--- a/database/postgres/pg.js
+++ b/database/postgres/pg.js
@@ -20,8 +20,9 @@ pgModule.closePGDB = () => {
return client.end();
};
-pgModule.createPgAccount = async (username, password) => {
- if (!username || !password) return;
+pgModule.createPgAccount = async (user) => {
+ const { username, dbPassword } = user;
+ if (!username || !dbPassword) return;
try {
// Could not escape user input by using $1 $2
// https://github.com/brianc/node-postgres/issues/539
@@ -30,7 +31,7 @@ pgModule.createPgAccount = async (username, password) => {
const sqlQuery2 = escape(
`create user %s with encrypted password %Q`,
username,
- password
+ dbPassword
);
const sqlQuery3 = escape(
diff --git a/database/postgres/pg.test.js b/database/postgres/pg.test.js
index 53b5abe2..63584b30 100644
--- a/database/postgres/pg.test.js
+++ b/database/postgres/pg.test.js
@@ -47,7 +47,8 @@ describe("Test PG DB", () => {
});
describe("Test createPgAccount", () => {
it("it should execute all queries if required arguments are passed into createPgAccount", async () => {
- await createPgAccount("username", "password");
+ const user = { username: "username", dbPassword: "password" };
+ await createPgAccount(user);
expect(mockClient.query).toHaveBeenCalledTimes(3);
expect(mockClient.query.mock.calls[0]).toEqual([
`CREATE DATABASE username;`,
@@ -65,16 +66,15 @@ describe("Test PG DB", () => {
]);
});
it("it should not execute any queries in createPgAccount if required arguments are not passed in", async () => {
- await createPgAccount();
+ const user = {};
+ await createPgAccount(user);
expect(mockClient.query).toHaveBeenCalledTimes(0);
});
it("it should check if logger.error is called at throw of createPgAccount", async () => {
try {
await mockClient.query.mockReturnValue(Promise.reject());
- const resCreatePgAccount = await createPgAccount(
- "username",
- "password"
- );
+ const user = { username: "username", dbPassword: "password" };
+ const resCreatePgAccount = await createPgAccount(user);
expect(resCreatePgAccount).rejects.toThrow();
} catch (err) {
expect(logger.error).toHaveBeenCalledTimes(1);
diff --git a/env.example b/env.example
index edf8144c..83bca08e 100644
--- a/env.example
+++ b/env.example
@@ -1,9 +1,31 @@
-HOST=databases.com
-PORT=3000
-PG_USER=username
-PASSWORD=password
-DATABASE=database
-DIALECT=postgres
-ALTER_DB=true
-MAILGUN_API_KEY=01234567890123456789
-MAILGUN_DOMAIN=databases.com
\ No newline at end of file
+#api key for mailing service
+MAILGUN_API_KEY=***
+#mailgun domain
+MAILGUN_DOMAIN=code3scape.com
+#testing port for jest
+TEST_PORT=30300
+#sequelize host adress
+HOST=104.168.169.204
+#sequelize postgres username
+PG_USER=***
+#sequelize postgres database name
+DATABASE=***
+#sequelize database password
+PASSWORD=***
+#sequelize allow to alter database: true/false
+ALTER_DB=true
+#password for session-express
+SECRET=***
+#Neo4j graph database url
+NEO4J_URL=neo4j://104.168.169.204
+#Neo4j username
+NEO4J_USER=***
+#Neo4j password
+NEO4J_PASSWORD=***
+#production/development flag, in jest tests this varible is "test" by default
+NODE_ENV = development
+#local port, default value 3052
+PORT = 3052
+#hostname adress, default is https://learndatabases.dev,
+#if you want to use localhost you need to specify port, for example http://localhost:4000
+HOSTNAME = https://learndatabases.dev
diff --git a/lib/getEnvVar.js b/lib/getEnvVar.js
deleted file mode 100644
index 08af531a..00000000
--- a/lib/getEnvVar.js
+++ /dev/null
@@ -1,8 +0,0 @@
-require('dotenv').config()
-
-module.exports = (type) => {
- if (type === 'mailgun') return {
- apiKey: process.env.MAILGUN_API_KEY || '123',
- domain: process.env.MAILGUN_DOMAIN
- }
-}
\ No newline at end of file
diff --git a/lib/getEnvVar.test.js b/lib/getEnvVar.test.js
deleted file mode 100644
index 0eafe3e8..00000000
--- a/lib/getEnvVar.test.js
+++ /dev/null
@@ -1,16 +0,0 @@
-describe('test getEnvVar', () => {
- it('should return mailgun env var', () => {
- process.env.MAILGUN_API_KEY = 'test key'
- const getEnvVar = require('./getEnvVar')
- expect(getEnvVar('mailgun').apiKey).toEqual('test key')
- })
- it('should return default mailgun env var', () => {
- delete process.env.MAILGUN_API_KEY
- const getEnvVar = require('./getEnvVar')
- expect(getEnvVar('mailgun').apiKey).toEqual('123')
- })
- it('should return nothing without argument', () => {
- const getEnvVar = require('./getEnvVar')
- expect(getEnvVar()).toEqual(undefined)
- })
-})
\ No newline at end of file
diff --git a/lib/users.js b/lib/users.js
index 742f344b..df03efe4 100644
--- a/lib/users.js
+++ b/lib/users.js
@@ -14,7 +14,7 @@ const {
const users = {};
const schema = yup.object().shape({
- email: yup.string().required().email(),
+ email: yup.string().nullable().email(),
});
users.sendPasswordResetEmail = async (userAccount) => {
@@ -38,35 +38,22 @@ users.sendPasswordResetEmail = async (userAccount) => {
};
users.signUp = async (userInfo) => {
- try {
- await schema.validate(userInfo);
- } catch (err) {
- throw new Error(err);
- }
-
- const { email } = userInfo;
- const { Accounts } = db.getModels();
- const userAccount = await Accounts.findOne({
- where: {
- email: email,
- },
- });
+ await schema.validate(userInfo);
const username = uniqueNamesGenerator({
length: 2,
- dictionaries: [adjectives, colors, animals],
+ dictionaries: [adjectives, animals],
separator: "",
});
const dbPassword = genPw();
- if (userAccount) {
- logger.info("this account already exists", email);
- throw new Error("this account already exists");
- }
+ const { Accounts } = db.getModels();
const newAccount = await Accounts.create({
- email: email,
+ email: userInfo.email,
username: username,
dbPassword: dbPassword,
});
- await users.sendPasswordResetEmail(newAccount);
+ if (userInfo.email) {
+ await users.sendPasswordResetEmail(newAccount);
+ }
return newAccount;
};
diff --git a/lib/users.test.js b/lib/users.test.js
index ee3be7e7..afe433c5 100644
--- a/lib/users.test.js
+++ b/lib/users.test.js
@@ -58,42 +58,47 @@ describe("Sign up", () => {
});
it("should throw an error if accounts already exists", () => {
- mockFindOne.mockImplementation((query) => {
- if (query.where.email) return { email: "1234@gmail.com" };
- if (query.where.username) return false;
+ mockCreateAccount.mockImplementation(() => {
+ throw new Error("This account already exists");
});
const obj = {
email: "1234@gmail.com",
};
- return expect(signUp(obj)).rejects.toThrow("this account already exists");
+ return expect(signUp(obj)).rejects.toThrow("This account already exists");
});
it("should create a user account", async () => {
- const dataValues = await genUserInfoWithPw("abcd1234");
- mockFindOne.mockImplementation((query) => {
- if (query.where.email) return undefined;
- if (query.where.username) return false;
+ const obj = { email: "test.user@databases.com" };
+ const dataValues = { ...obj, username: "testuser", dbPassword: "database" };
+ mockCreateAccount.mockReturnValue({
+ dataValues: dataValues,
+ update: () => {},
});
+ const data = await signUp(obj);
+ expect(data.dataValues).toEqual(dataValues);
+ });
+
+ it("should create a anonymous user account", async () => {
+ const obj = {};
+ const dataValues = { username: "testuser", dbPassword: "database" };
mockCreateAccount.mockReturnValue({
dataValues: dataValues,
update: () => {},
});
- const obj = {
- email: "test.user@databases.com",
- };
const data = await signUp(obj);
expect(data.dataValues).toEqual(dataValues);
+ expect(email.sendPasswordResetEmail).not.toHaveBeenCalled();
});
it("should send a user set Password email", async () => {
- const obj = {
- id: 4,
- email: "em@i.l",
- update: jest.fn(),
- };
-
- await sendPasswordResetEmail(obj);
- expect(email.sendPasswordResetEmail.mock.calls.length).toEqual(1);
+ const obj = { email: "test.user@databases.com" };
+ const dataValues = { ...obj, username: "testuser", dbPassword: "database" };
+ mockCreateAccount.mockReturnValue({
+ dataValues: dataValues,
+ update: () => {},
+ });
+ await signUp(obj);
+ expect(email.sendPasswordResetEmail).toHaveBeenCalled();
});
});
diff --git a/sequelize/db.js b/sequelize/db.js
index cb0fcc29..521e4cbd 100644
--- a/sequelize/db.js
+++ b/sequelize/db.js
@@ -35,6 +35,7 @@ dbModule.start = async () => {
email: {
type: DataTypes.STRING,
unique: true,
+ allowNull: true,
},
dbPassword: {
type: DataTypes.STRING,
diff --git a/services/__snapshots__/mailer.test.js.snap b/services/__snapshots__/mailer.test.js.snap
index fa77bf87..2b44a815 100644
--- a/services/__snapshots__/mailer.test.js.snap
+++ b/services/__snapshots__/mailer.test.js.snap
@@ -9,7 +9,7 @@ Object {
You have requested a (re)set password token. The button below will redirect you to our website with an autheticated token. Please click the button and set your password.
You have requested a (re)set password token. The button below will redirect you to our website with an autheticated token. Please click the button and set your password.
In this module, you can learn how to use ${database}. Don't have ${database} installed on your local machine yet? Fear not! We can make a ${database} database for you. Please login first to create your database. If you want, you may keep reading this tutorial without login.
In this module, you can learn how to use ${database}. Don't have ${database} installed on your local machine yet? Fear not! We can make an ${database} database for you. Simply click on the button below to create your ${database} database. Credentials for your database will appear after it is done being created.
-
- `
- } else {
- introduction.innerHTML = `
-
In this module, you can learn how to use ${database}. You have already created an ${database} database on our server. Here are the credentials for your database.
In this module, you can learn how to use ${database}. Don't have ${database} installed on your local machine yet? Fear not! We can make a ${database} database for you. Simply click on the button below to create your temporary ${database} database. Credentials for your database will appear after it is done being created.
+
Temporary database credentials will expire in 5 days. If you want, you can sign up with us and get a non-expiring Postgres database!
In this module, you can learn how to use ${database}. Don't have ${database} installed on your local machine yet? Fear not! We can make an ${database} database for you. Simply click on the button below to create your ${database} database. Credentials for your database will appear after it is done being created.
In this module, you can learn how to use ${database}. You have already created an ${database} database on our server. Here are the credentials for your database.