diff --git a/client/App.js b/client/App.js
index 9e8f374..6513778 100644
--- a/client/App.js
+++ b/client/App.js
@@ -1,20 +1,22 @@
import React from 'react';
-import {createStore, applyMiddleware} from 'redux';
-import {Provider} from 'react-redux';
-import reducer from './src/redux/reducer';
-import thunk from 'redux-thunk';
-import Dashboard from './src/components/Dashboard';
+import { createStore, applyMiddleware } from 'redux'
+import { Provider } from 'react-redux'
+import reducer from './src/redux/reducer'
+import thunk from 'redux-thunk'
+import Dashboard from './src/components/Dashboard'
+import Login from './src/components/Login'
import NoteList from './src/components/NoteList';
-import {createAppContainer} from 'react-navigation';
-import {createStackNavigator} from 'react-navigation-stack';
+import { createAppContainer } from 'react-navigation';
+import { createStackNavigator } from 'react-navigation-stack';
-import {View, StyleSheet, Text} from 'react-native';
+import { View, StyleSheet, Text } from 'react-native';
const navigationStak = createStackNavigator({
- Dashboard: {screen: Dashboard},
- NoteList: {screen: NoteList},
+ Login: { screen: Login },
+ Dashboard: { screen: Dashboard },
+ NoteList: { screen: NoteList },
});
const store = createStore(reducer, applyMiddleware(thunk));
diff --git a/client/src/components/Dashboard/index.js b/client/src/components/Dashboard/index.js
index 46dafd1..09fa2b6 100644
--- a/client/src/components/Dashboard/index.js
+++ b/client/src/components/Dashboard/index.js
@@ -1,5 +1,5 @@
import React from 'react'
-import { getAllCategories } from '../../redux/action'
+import { getAllCategories, logOut } from '../../redux/action'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
@@ -10,6 +10,8 @@ import {
View,
FlatList,
Image,
+ Button,
+ TouchableOpacity
} from 'react-native';
class Dashboard extends React.Component {
@@ -18,32 +20,41 @@ class Dashboard extends React.Component {
this.props.getAllCategories()
}
moveToList = () => {
- // this should done after someye complete her work
- // this.props.navigation.navigate('noteList')
+ this.props.navigation.navigate('NoteList')
+ }
+ logedOut = () => {
+ this.props.logOut()
+ this.props.navigation.navigate('Login')
}
- render() {
+ render() {
return (
+ {this.props.loading || !this.props.login ? loading
+
+ :
+ (
- {this.props.loading ? Loading : (
- <>
-
- (
-
+ <>
+
- )} />
- >
- )
+
+ (
+
+
+
+
+ {item["name"]}
+
+ )} />
+ >
+ )
}
@@ -69,13 +80,16 @@ const styles = StyleSheet.create({
const mapStateToProps = (state) => {
return {
categories: state.categories,
- loading: state.loading
+ loading: state.loading,
+ logout: state.logout,
+ login: state.login
}
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
getAllCategories,
+ logOut,
}, dispatch)
}
diff --git a/client/src/components/Login/index.js b/client/src/components/Login/index.js
new file mode 100644
index 0000000..4f7b7ea
--- /dev/null
+++ b/client/src/components/Login/index.js
@@ -0,0 +1,141 @@
+import React, { Component } from 'react'
+import axios from 'axios'
+import {
+ View,
+ Text,
+ Button,
+ TextInput,
+ StyleSheet,
+ Image,
+ TouchableOpacity
+} from 'react-native';
+import { connect } from 'react-redux'
+import { bindActionCreators } from 'redux'
+import { checkLogin } from '../../redux/action'
+
+class Login extends Component {
+ state = {
+ email: "",
+ password: "",
+ errorMsg: "",
+ };
+
+ handleInputEmail = email => {
+ this.setState({ email });
+ };
+
+ handleInputPassword = password => {
+ this.setState({ password });
+ };
+
+ logedIn = () => {
+ const { email, password } = this.state
+ this.props.checkLogin(email, password)
+ const { login } = this.props;
+ if (login || this.props.loading) {
+ this.props.navigation.push('Dashboard')
+ }
+ else {
+ alert('email or password is not correct')
+ }
+
+ };
+ signup = () => {
+ alert('in progress')
+ // this.props.navigation.push('Signup')
+ }
+ render() {
+
+
+ return (
+
+ Welcome to Notepad
+
+
+
+ {/*
+ )
+ }
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ marginTop: 1,
+ },
+ title: {
+ textAlign: 'center',
+ fontStyle: "italic",
+ lineHeight: 25,
+ },
+ textBox: {
+ width: 250,
+ height: 40,
+ borderRadius: 25,
+ borderColor: "#E5E8E8",
+ borderWidth: 0.5,
+ paddingHorizontal: 16,
+ fontSize: 14,
+ marginVertical: 10
+ },
+ button: {
+ width: 120,
+ height: 40,
+ backgroundColor: '#fff',
+ borderColor: "#E5E8E8",
+ borderRadius: 50,
+ borderWidth: 0.5,
+ marginVertical: 10,
+ paddingVertical: 6
+
+ },
+ buttonText: {
+ fontSize: 16,
+ fontWeight: '500',
+ color: 'black',
+ textAlign: 'center',
+ },
+ signupTextCont: {
+ flexGrow: 1,
+ alignItems: 'flex-end',
+ justifyContent: 'center',
+ paddingVertical: 22,
+ flexDirection: 'row'
+ },
+ signupText: {
+ color: '#000',
+ fontSize: 14
+ },
+ signupButton: {
+ color: 'blue',
+ fontSize: 14,
+ fontWeight: '500'
+ },
+})
+
+
+const mapStateToProps = (state) => {
+ return {
+ login: state.login,
+ loading: state.loading,
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return bindActionCreators({
+ checkLogin,
+ }, dispatch)
+}
+export default connect(mapStateToProps, mapDispatchToProps)(Login)
\ No newline at end of file
diff --git a/client/src/components/NoteList/index.js b/client/src/components/NoteList/index.js
index 44cb67b..3741bf2 100644
--- a/client/src/components/NoteList/index.js
+++ b/client/src/components/NoteList/index.js
@@ -1,8 +1,8 @@
-import React, {Component} from 'react';
-import {Text, View, FlatList, StyleSheet,ScrollView} from 'react-native';
-import {connect} from 'react-redux';
-import {bindActionCreators} from 'redux';
-import {getAllNotes} from '../../redux/action';
+import React, { Component } from 'react';
+import { Text, View, FlatList, StyleSheet, ScrollView } from 'react-native';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { getAllNotes } from '../../redux/action';
class NoteList extends Component {
componentDidMount = () => {
@@ -16,20 +16,20 @@ class NoteList extends Component {
{this.props.loading ? (
Loading
) : (
- <>
-
- (
-
- {item['note_text']}
- {item['post_date']}
-
- )}
- />
-
- >
- )}
+ <>
+
+ (
+
+ {item['note_text']}
+ {item['post_date']}
+
+ )}
+ />
+
+ >
+ )}
);
}
diff --git a/client/src/redux/action.js b/client/src/redux/action.js
index 88eb031..80bafc9 100644
--- a/client/src/redux/action.js
+++ b/client/src/redux/action.js
@@ -1,11 +1,19 @@
//actions
-import axios from 'axios';
+import axios from 'axios'
+
+export const getAllCategories = () => async (dispatch) => {
+ dispatch({
+ type: 'LOADING',
+ loading: true
+
+ });
-export const getAllCategories = () => async dispatch => {
try {
- const response = await axios.get('http://192.168.13.70:4000/api/dashboard');
- const data = response.data;
+
+ const response = await axios.get("http://192.168.13.248:4000/api/dashboard")
+
+ const data = response.data
dispatch({
type: 'GET_ALL_CATEGORIES',
@@ -21,7 +29,7 @@ export const getAllCategories = () => async dispatch => {
export const getAllNotes = (category_id, user_id) => async dispatch => {
try {
const response = await axios.get(
- `http://192.168.13.170:4000/api/dashboard/${category_id}/${user_id}/notes`,
+ `http://192.168.13.248:4000/api/dashboard/${category_id}/${user_id}/notes`,
);
const data = response.data;
@@ -37,4 +45,44 @@ export const getAllNotes = (category_id, user_id) => async dispatch => {
type: 'LOADING',
});
}
-};
+
+}
+
+
+export const checkLogin = (email, password) => async (dispatch) => {
+ dispatch({
+ type: 'LOADING',
+ loading: true
+ })
+
+ try {
+
+ const data = await axios.post("http://192.168.13.248:4000/api/login", { email, password })
+ const login = data.data.msg
+
+ dispatch({
+ type: 'LOGIN',
+ login,
+ loading: false
+ })
+ }
+ catch {
+ dispatch({
+ type: 'LOADING',
+ loading: true,
+ login: false
+
+ })
+ }
+}
+
+export const logOut = () => async (dispatch) => {
+
+ const data = await axios.get("http://192.168.13.248:4000/api/logout")
+ const logout = data.data.message;
+ dispatch({
+ type: 'LOGOUT',
+ logout
+ })
+
+}
diff --git a/client/src/redux/reducer.js b/client/src/redux/reducer.js
index 3da8772..dd89e81 100644
--- a/client/src/redux/reducer.js
+++ b/client/src/redux/reducer.js
@@ -2,29 +2,41 @@ const initialState = {
categories: [],
notes: [],
loading: true,
-};
+ login: false,
+ logout: false,
+}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'GET_ALL_CATEGORIES':
return {
...state,
- categories: state.categories.concat(action.data),
- loading: false,
- };
+ categories: action.data,
+ loading: action.loading,
+ }
+ case 'LOADING':
+ return {
+ ...state,
+ loading: action.loading
+ }
+ case "LOGIN":
+ return {
+ ...state,
+ login: action.login,
+ loading: action.loading,
+ }
+ case "LOGOUT":
+ return {
+ ...state,
+ logout: action.logout
+ }
case 'GET_ALL_NOTES':
return {
...state,
notes: state.notes.concat(action.data.data),
loading: false,
};
- case 'LOADING':
- return {
- ...state,
- loading: true,
- };
- default:
- return state;
+ default: return state
}
};
export default reducer;
diff --git a/package.json b/package.json
index 74ef9c4..88402f9 100644
--- a/package.json
+++ b/package.json
@@ -4,9 +4,11 @@
"description": "The app is an a simple small notepad allowing creating and editing text notes, which they categorized as a group of categories.",
"main": "index.js",
"dependencies": {
+ "bcrypt": "^3.0.7",
"concurrently": "^5.0.0",
"env2": "^2.2.2",
"express": "^4.17.1",
+ "jsonwebtoken": "^8.5.1",
"nodemon": "^1.19.4",
"pg": "^7.12.1"
},
diff --git a/server/controllers/checkAuth.js b/server/controllers/checkAuth.js
new file mode 100644
index 0000000..c57785d
--- /dev/null
+++ b/server/controllers/checkAuth.js
@@ -0,0 +1,4 @@
+exports.checkAuth = (req, res) => {
+ const { name } = req
+ res.json({ success: true, username: name })
+}
\ No newline at end of file
diff --git a/server/controllers/index.js b/server/controllers/index.js
index 7c8722d..744265b 100644
--- a/server/controllers/index.js
+++ b/server/controllers/index.js
@@ -1,11 +1,16 @@
const express = require('express')
+const login = require('./login')
+const { auth } = require('../middlewares/auth')
+const { checkAuth } = require('./checkAuth')
const router = express.Router()
+const logout = require('./logout')
const { getAllCategories } = require('./getAllCategories')
-const { getNote }= require('./getNote')
-
+const { getNote } = require('./getNote')
router.get('/api/dashboard/:category_id/:user_id/notes', getNote);
-router.get('/api/dashboard', getAllCategories)
+router.get('/api/dashboard', auth, getAllCategories)
+router.post('/api/login', login.get)
+router.get('/api/logout', logout.get)
module.exports = router
diff --git a/server/controllers/login.js b/server/controllers/login.js
new file mode 100644
index 0000000..6057f4c
--- /dev/null
+++ b/server/controllers/login.js
@@ -0,0 +1,31 @@
+const checkUser = require('../database/queries/checkUser.js')
+const bcrypt = require('bcrypt')
+var jwt = require('jsonwebtoken')
+
+exports.get = (req, res) => {
+ console.log("rr");
+
+ const { email, password } = req.body
+
+ checkUser(email)
+ .then(data => {
+ const dddd = data.rows[0]
+ bcrypt.compare(password, dddd.password, (err, result) => {
+
+
+ if (result) {
+
+ const { user_id, name } = data
+ const token = jwt.sign(
+ { email, user_id: user_id, name: name },
+ process.env.SECRET)
+ return res
+ .cookie('token', token, { maxAge: 99999999 })
+ .json({ msg: true, token })
+ } else {
+ return res.json({ msg: false })
+ }
+ })
+ })
+ .catch(err => res.json({ msg: false }))
+}
\ No newline at end of file
diff --git a/server/controllers/logout.js b/server/controllers/logout.js
new file mode 100644
index 0000000..2bf2d93
--- /dev/null
+++ b/server/controllers/logout.js
@@ -0,0 +1,4 @@
+exports.get = (req, res) => {
+ res.clearCookie('token')
+ res.json({ message: 'true' })
+}
\ No newline at end of file
diff --git a/server/database/db_build.js b/server/database/db_build.js
index dab87c7..d9550d1 100644
--- a/server/database/db_build.js
+++ b/server/database/db_build.js
@@ -1,6 +1,5 @@
const fs = require('fs')
const path = require('path')
-
const dbConnection = require('./db_connection')
const sql = fs.readFileSync(path.join(__dirname, 'db_build.sql')).toString()
@@ -14,7 +13,6 @@ const runDbBuild = (sql, sql2) => {
})
.catch(err => err)
}
-
runDbBuild(sql, sql2)
module.exports = runDbBuild
\ No newline at end of file
diff --git a/server/database/fake_data_build.sql b/server/database/fake_data_build.sql
index fa8e48a..fef7847 100644
--- a/server/database/fake_data_build.sql
+++ b/server/database/fake_data_build.sql
@@ -1,7 +1,7 @@
BEGIN;
Insert into users_accounts(name, email, password) values('yaqoot', 'yaqoot@gmail.com', 1511),
- ('duaa', 'duaa@gmail.com', 147), ('someya', 'someya@gmail.com', 123456);
+ ('duaa', 'duaa@gmail.com', '$2a$10$D/IX/AtYw5YHT4YWI2B2aOg5ZGMBodHNDx2x6vIbHWomyH4fsJ9SG'), ('someya', 'someya@gmail.com', 123456);
Insert into category(name, image) values('Work', 'https://i.pinimg.com/564x/b8/2d/77/b82d77b291c7dd35e8a9c7ca9b268070.jpg'),
('Home', 'https://i.pinimg.com/564x/18/37/7a/18377abb31b8fde5a15c709e0dc77047.jpg'), ('Exercise', 'https://i.pinimg.com/564x/ed/56/c3/ed56c3c9b5f0491e64559515fb8cd738.jpg'), ('Study', 'https://i.pinimg.com/564x/5d/23/f1/5d23f15fc4c4fe0d89f56bbf5d1fa1a2.jpg');
diff --git a/server/database/queries/checkUser.js b/server/database/queries/checkUser.js
new file mode 100644
index 0000000..de321ed
--- /dev/null
+++ b/server/database/queries/checkUser.js
@@ -0,0 +1,12 @@
+const dbConnection = require("./../db_connection")
+
+const checkUser = email => {
+ return dbConnection
+ .query(
+ "select password, user_id, name from users_accounts where email = $1",
+ [email]
+ )
+
+}
+
+module.exports = checkUser
\ No newline at end of file
diff --git a/server/middlewares/auth.js b/server/middlewares/auth.js
new file mode 100644
index 0000000..cfa72be
--- /dev/null
+++ b/server/middlewares/auth.js
@@ -0,0 +1,24 @@
+const cookie = require('cookie')
+const { verify } = require('jsonwebtoken')
+const SECRET = process.env.SECRET
+
+exports.auth = (req, res, next) => {
+ if (req.headers.cookie) {
+ const { token } = cookie.parse(req.headers.cookie)
+ verify(token, SECRET, (err, result) => {
+ if (err) {
+ return res.json({ error: 'server error', success: false })
+ }
+ if (result) {
+ req.user_id = result.user_id
+ req.name = result.name
+
+ return next()
+ } else {
+ return res.json({ error: 'not Authorized', success: false })
+ }
+ })
+ } else {
+ return res.json({ error: 'not Authorized', success: false })
+ }
+}
\ No newline at end of file