SlideShare a Scribd company logo
1 of 21
Download to read offline
Creating a WhatsApp Clone - Part XI
We are finally back to the Spring Boot server we setup initially. The code here is pretty simple as well.
package com.codename1.whatsapp.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WhatsAppApplication {
public static void main(String[] args) {
SpringApplication.run(WhatsAppApplication.class, args);
}
}
WhatsAppApplication
The WhatsAppApplication is the boilerplate main class of the spring boot project, there isn’t much here and I’m only mentioning it for completeness
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/").permitAll();
httpSecurity.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
SecurityConfiguration
Security configuration is a bit more interesting although again it’s similar to what we saw in previous projects.

First we need to permit all requests to remove some HTTP security limits. We don’t need them here since this isn’t a webapp
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/").permitAll();
httpSecurity.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
SecurityConfiguration
Similarly we need to disable csrf protection as it isn’t applicable for native apps
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/").permitAll();
httpSecurity.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
SecurityConfiguration
Finally we need to provide a password encoder implementation, we’ll use this to encrypt the tokens in the database
@Entity
@Indexed
public class User {
@Id
private String id;
@Field
private String name;
@Field
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
User
Next lets go into the entity objects. I won’t go into what entities are as I discussed them a lot in the previous modules. They are effectively an abstraction of the
underlying data store. The user entity represents the data we save for a chat contact
@Entity
@Indexed
public class User {
@Id
private String id;
@Field
private String name;
@Field
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
User
I use a string unique id with a universal unique identifier which is more secure as I mentioned before. It might make sense to use the phone as the id value though.
@Entity
@Indexed
public class User {
@Id
private String id;
@Field
private String name;
@Field
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
User
The user name and tagline are also stored similarly to the client side code
@Entity
@Indexed
public class User {
@Id
private String id;
@Field
private String name;
@Field
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
User
Phone is listed as unique which makes sure the value is unique in the database
@Id
private String id;
@Field
private String name;
@Field
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
@ManyToOne
private Media avatar;
@Column(unique=true)
private String authtoken;
User
When we send a verification code we store it in the database. I could use a distributed caching system like redis or memcached but they're an overkill for something as
simple as this
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
@ManyToOne
private Media avatar;
@Column(unique=true)
private String authtoken;
private String pushKey;
private boolean verified;
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
User
The date in which the user entry was created is a standard database date
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
@ManyToOne
private Media avatar;
@Column(unique=true)
private String authtoken;
private String pushKey;
private boolean verified;
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
User
This isn’t used at this time but it’s very similar to the code we have in the facebook clone to store media. In fact it’s copied from there and we can refer to that for media
storage/upload.
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
@ManyToOne
private Media avatar;
@Column(unique=true)
private String authtoken;
private String pushKey;
private boolean verified;
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
User
The authtoken is effectively a combination of username and password. As such it’s hashed and as such only the user device knows that value. I believe that’s how
whatsapp works, that's why only one device can connect to a whatsapp account. Since the token is hashed when you need to retrieve an access token you need to
effectively delete the last token and create a new one in order to setup a hash.

For the uninitiated a hash is an encrypted value that can only be generated but not retrieved. So if my password is “password” and the hash is “xyzjkl” then I can’t get the
value of the password from the hash. But I can check that “password" matches “xyzjkl”. Hashes are also salted so they have 60 characters in length and strong hashes
are impossible to crack with standard tools.
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
@ManyToOne
private Media avatar;
@Column(unique=true)
private String authtoken;
private String pushKey;
private boolean verified;
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
User
The push key is the key used to send push messages to the client device
private String tagline;
@Column(unique=true)
private String phone;
private String verificationCode;
@Temporal(TemporalType.DATE)
private Date creationDate;
@ManyToOne
private Media avatar;
@Column(unique=true)
private String authtoken;
private String pushKey;
private boolean verified;
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
User
This flag indicates whether a user is verified
private String authtoken;
private String pushKey;
private boolean verified;
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
}
public UserDAO getDAO() {
return new UserDAO(id, name, tagline, phone, creationDate,
avatar == null ? null : avatar.getId());
}
public UserDAO getLoginDAO() {
UserDAO d = getDAO();
d.setToken(authtoken);
return d;
}
/**
User
When we create a new user we initialize the id and creation date sensibly. If this entity is loaded from the database these values will be overridden.
public User() {
id = UUID.randomUUID().toString();
creationDate = new Date();
}
public UserDAO getDAO() {
return new UserDAO(id, name, tagline, phone, creationDate,
avatar == null ? null : avatar.getId());
}
public UserDAO getLoginDAO() {
UserDAO d = getDAO();
d.setToken(authtoken);
return d;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
User
The DAO methods create a data access object that we can send to the client. We will make use of them later in the service code
package com.codename1.whatsapp.server.entities;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, String> {
public List<User> findByPhone(String phone);
public List<User> findByAuthtoken(String authtoken);
public List<User> findByPushKey(String pushKey);
}
UserRepository
The user repository maps to the User object and exposes 3 finder methods.

We use findByPhone during signup and sending to detect the user with the given phone
package com.codename1.whatsapp.server.entities;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, String> {
public List<User> findByPhone(String phone);
public List<User> findByAuthtoken(String authtoken);
public List<User> findByPushKey(String pushKey);
}
UserRepository
This method should be removed as it’s part of copy and pasted media entity code
package com.codename1.whatsapp.server.entities;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, String> {
public List<User> findByPhone(String phone);
public List<User> findByAuthtoken(String authtoken);
public List<User> findByPushKey(String pushKey);
}
UserRepository
We need to find by push key in order to remove or update expired push keys. If the server returns an error we need to update that.
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class UserDAO {
private String id;
private String name;
private String tagline;
private String phone;
@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS")
private Date creationDate;
private String avatar;
private String token;
public UserDAO() {
}
public UserDAO(String id, String name, String tagline, String phone, Date
creationDate,
String avatar) {
this.id = id;
this.name = name;
UserDAO
UserDAO is a pretty much the content of the user class, there isn't much to discuss here with one major exception and that’s the JSON format annotation. Here we
explicitly declare how we want the Date object to translate to JSON when it’s sent to the client. This is the standard JSON pattern and Codename One in the client side
knows how to parse this

More Related Content

Similar to Creating a Whatsapp Clone - Part XI - Transcript.pdf

JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile
JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobileJavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile
JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobileLoiane Groner
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XXXI - Transcript.pdf
Creating a Facebook Clone - Part XXXI - Transcript.pdfCreating a Facebook Clone - Part XXXI - Transcript.pdf
Creating a Facebook Clone - Part XXXI - Transcript.pdfShaiAlmog1
 
DAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docx
DAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docxDAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docx
DAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docxtheodorelove43763
 
Creating a Facebook Clone - Part XVII.pdf
Creating a Facebook Clone - Part XVII.pdfCreating a Facebook Clone - Part XVII.pdf
Creating a Facebook Clone - Part XVII.pdfShaiAlmog1
 
Kotlin Data Model
Kotlin Data ModelKotlin Data Model
Kotlin Data ModelKros Huang
 
Creating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdfCreating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdfShaiAlmog1
 
I really need some help if I have this right so far. PLEASE CHANG.pdf
I really need some help if I have this right so far. PLEASE CHANG.pdfI really need some help if I have this right so far. PLEASE CHANG.pdf
I really need some help if I have this right so far. PLEASE CHANG.pdfaggarwalshoppe14
 
Overview You are tasked with writing a program called Social Security.pdf
Overview You are tasked with writing a program called Social Security.pdfOverview You are tasked with writing a program called Social Security.pdf
Overview You are tasked with writing a program called Social Security.pdfinfo961251
 
Open Selector
Open SelectorOpen Selector
Open Selectorjjdelc
 
Introduction to Spring Boot.pdf
Introduction to Spring Boot.pdfIntroduction to Spring Boot.pdf
Introduction to Spring Boot.pdfShaiAlmog1
 
So here is the code from the previous assignment that we need to ext.pdf
So here is the code from the previous assignment that we need to ext.pdfSo here is the code from the previous assignment that we need to ext.pdf
So here is the code from the previous assignment that we need to ext.pdfleolight2
 
Creating a Facebook Clone - Part XXI.pdf
Creating a Facebook Clone - Part XXI.pdfCreating a Facebook Clone - Part XXI.pdf
Creating a Facebook Clone - Part XXI.pdfShaiAlmog1
 
I really need some help if I have this right so far. Please Resub.pdf
I really need some help if I have this right so far. Please Resub.pdfI really need some help if I have this right so far. Please Resub.pdf
I really need some help if I have this right so far. Please Resub.pdfaggarwalshoppe14
 
Use the code below from the previous assignment that we need to exte.pdf
Use the code below from the previous assignment that we need to exte.pdfUse the code below from the previous assignment that we need to exte.pdf
Use the code below from the previous assignment that we need to exte.pdfsales87
 
Code to copy Person.java .pdf
Code to copy Person.java .pdfCode to copy Person.java .pdf
Code to copy Person.java .pdfanokhijew
 
Creating a Facebook Clone - Part XLV.pdf
Creating a Facebook Clone - Part XLV.pdfCreating a Facebook Clone - Part XLV.pdf
Creating a Facebook Clone - Part XLV.pdfShaiAlmog1
 

Similar to Creating a Whatsapp Clone - Part XI - Transcript.pdf (20)

JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile
JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobileJavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile
JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Facebook Clone - Part XXXI - Transcript.pdf
Creating a Facebook Clone - Part XXXI - Transcript.pdfCreating a Facebook Clone - Part XXXI - Transcript.pdf
Creating a Facebook Clone - Part XXXI - Transcript.pdf
 
DAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docx
DAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docxDAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docx
DAOFactory.javaDAOFactory.javapublicclassDAOFactory{ this .docx
 
Manual tecnic sergi_subirats
Manual tecnic sergi_subiratsManual tecnic sergi_subirats
Manual tecnic sergi_subirats
 
Creating a Facebook Clone - Part XVII.pdf
Creating a Facebook Clone - Part XVII.pdfCreating a Facebook Clone - Part XVII.pdf
Creating a Facebook Clone - Part XVII.pdf
 
Kotlin Data Model
Kotlin Data ModelKotlin Data Model
Kotlin Data Model
 
Java Persistence API
Java Persistence APIJava Persistence API
Java Persistence API
 
Creating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdfCreating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdf
 
I really need some help if I have this right so far. PLEASE CHANG.pdf
I really need some help if I have this right so far. PLEASE CHANG.pdfI really need some help if I have this right so far. PLEASE CHANG.pdf
I really need some help if I have this right so far. PLEASE CHANG.pdf
 
Overview You are tasked with writing a program called Social Security.pdf
Overview You are tasked with writing a program called Social Security.pdfOverview You are tasked with writing a program called Social Security.pdf
Overview You are tasked with writing a program called Social Security.pdf
 
Open Selector
Open SelectorOpen Selector
Open Selector
 
Introduction to Spring Boot.pdf
Introduction to Spring Boot.pdfIntroduction to Spring Boot.pdf
Introduction to Spring Boot.pdf
 
So here is the code from the previous assignment that we need to ext.pdf
So here is the code from the previous assignment that we need to ext.pdfSo here is the code from the previous assignment that we need to ext.pdf
So here is the code from the previous assignment that we need to ext.pdf
 
Creating a Facebook Clone - Part XXI.pdf
Creating a Facebook Clone - Part XXI.pdfCreating a Facebook Clone - Part XXI.pdf
Creating a Facebook Clone - Part XXI.pdf
 
I really need some help if I have this right so far. Please Resub.pdf
I really need some help if I have this right so far. Please Resub.pdfI really need some help if I have this right so far. Please Resub.pdf
I really need some help if I have this right so far. Please Resub.pdf
 
Use the code below from the previous assignment that we need to exte.pdf
Use the code below from the previous assignment that we need to exte.pdfUse the code below from the previous assignment that we need to exte.pdf
Use the code below from the previous assignment that we need to exte.pdf
 
4.Spring IoC&DI(Spring Ioc실습_어노테이션 기반)
4.Spring IoC&DI(Spring Ioc실습_어노테이션 기반)4.Spring IoC&DI(Spring Ioc실습_어노테이션 기반)
4.Spring IoC&DI(Spring Ioc실습_어노테이션 기반)
 
Code to copy Person.java .pdf
Code to copy Person.java .pdfCode to copy Person.java .pdf
Code to copy Person.java .pdf
 
Creating a Facebook Clone - Part XLV.pdf
Creating a Facebook Clone - Part XLV.pdfCreating a Facebook Clone - Part XLV.pdf
Creating a Facebook Clone - Part XLV.pdf
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfShaiAlmog1
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdf
 

Recently uploaded

WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 

Recently uploaded (20)

WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 

Creating a Whatsapp Clone - Part XI - Transcript.pdf

  • 1. Creating a WhatsApp Clone - Part XI We are finally back to the Spring Boot server we setup initially. The code here is pretty simple as well.
  • 2. package com.codename1.whatsapp.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class WhatsAppApplication { public static void main(String[] args) { SpringApplication.run(WhatsAppApplication.class, args); } } WhatsAppApplication The WhatsAppApplication is the boilerplate main class of the spring boot project, there isn’t much here and I’m only mentioning it for completeness
  • 3. @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests().antMatchers("/").permitAll(); httpSecurity.csrf().disable(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } SecurityConfiguration Security configuration is a bit more interesting although again it’s similar to what we saw in previous projects. First we need to permit all requests to remove some HTTP security limits. We don’t need them here since this isn’t a webapp
  • 4. @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests().antMatchers("/").permitAll(); httpSecurity.csrf().disable(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } SecurityConfiguration Similarly we need to disable csrf protection as it isn’t applicable for native apps
  • 5. @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests().antMatchers("/").permitAll(); httpSecurity.csrf().disable(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } SecurityConfiguration Finally we need to provide a password encoder implementation, we’ll use this to encrypt the tokens in the database
  • 6. @Entity @Indexed public class User { @Id private String id; @Field private String name; @Field private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; User Next lets go into the entity objects. I won’t go into what entities are as I discussed them a lot in the previous modules. They are effectively an abstraction of the underlying data store. The user entity represents the data we save for a chat contact
  • 7. @Entity @Indexed public class User { @Id private String id; @Field private String name; @Field private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; User I use a string unique id with a universal unique identifier which is more secure as I mentioned before. It might make sense to use the phone as the id value though.
  • 8. @Entity @Indexed public class User { @Id private String id; @Field private String name; @Field private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; User The user name and tagline are also stored similarly to the client side code
  • 9. @Entity @Indexed public class User { @Id private String id; @Field private String name; @Field private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; User Phone is listed as unique which makes sure the value is unique in the database
  • 10. @Id private String id; @Field private String name; @Field private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; @ManyToOne private Media avatar; @Column(unique=true) private String authtoken; User When we send a verification code we store it in the database. I could use a distributed caching system like redis or memcached but they're an overkill for something as simple as this
  • 11. private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; @ManyToOne private Media avatar; @Column(unique=true) private String authtoken; private String pushKey; private boolean verified; public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); User The date in which the user entry was created is a standard database date
  • 12. private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; @ManyToOne private Media avatar; @Column(unique=true) private String authtoken; private String pushKey; private boolean verified; public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); User This isn’t used at this time but it’s very similar to the code we have in the facebook clone to store media. In fact it’s copied from there and we can refer to that for media storage/upload.
  • 13. private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; @ManyToOne private Media avatar; @Column(unique=true) private String authtoken; private String pushKey; private boolean verified; public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); User The authtoken is effectively a combination of username and password. As such it’s hashed and as such only the user device knows that value. I believe that’s how whatsapp works, that's why only one device can connect to a whatsapp account. Since the token is hashed when you need to retrieve an access token you need to effectively delete the last token and create a new one in order to setup a hash. For the uninitiated a hash is an encrypted value that can only be generated but not retrieved. So if my password is “password” and the hash is “xyzjkl” then I can’t get the value of the password from the hash. But I can check that “password" matches “xyzjkl”. Hashes are also salted so they have 60 characters in length and strong hashes are impossible to crack with standard tools.
  • 14. private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; @ManyToOne private Media avatar; @Column(unique=true) private String authtoken; private String pushKey; private boolean verified; public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); User The push key is the key used to send push messages to the client device
  • 15. private String tagline; @Column(unique=true) private String phone; private String verificationCode; @Temporal(TemporalType.DATE) private Date creationDate; @ManyToOne private Media avatar; @Column(unique=true) private String authtoken; private String pushKey; private boolean verified; public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); User This flag indicates whether a user is verified
  • 16. private String authtoken; private String pushKey; private boolean verified; public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); } public UserDAO getDAO() { return new UserDAO(id, name, tagline, phone, creationDate, avatar == null ? null : avatar.getId()); } public UserDAO getLoginDAO() { UserDAO d = getDAO(); d.setToken(authtoken); return d; } /** User When we create a new user we initialize the id and creation date sensibly. If this entity is loaded from the database these values will be overridden.
  • 17. public User() { id = UUID.randomUUID().toString(); creationDate = new Date(); } public UserDAO getDAO() { return new UserDAO(id, name, tagline, phone, creationDate, avatar == null ? null : avatar.getId()); } public UserDAO getLoginDAO() { UserDAO d = getDAO(); d.setToken(authtoken); return d; } /** * @return the id */ public String getId() { return id; } /** User The DAO methods create a data access object that we can send to the client. We will make use of them later in the service code
  • 18. package com.codename1.whatsapp.server.entities; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface UserRepository extends CrudRepository<User, String> { public List<User> findByPhone(String phone); public List<User> findByAuthtoken(String authtoken); public List<User> findByPushKey(String pushKey); } UserRepository The user repository maps to the User object and exposes 3 finder methods. We use findByPhone during signup and sending to detect the user with the given phone
  • 19. package com.codename1.whatsapp.server.entities; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface UserRepository extends CrudRepository<User, String> { public List<User> findByPhone(String phone); public List<User> findByAuthtoken(String authtoken); public List<User> findByPushKey(String pushKey); } UserRepository This method should be removed as it’s part of copy and pasted media entity code
  • 20. package com.codename1.whatsapp.server.entities; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface UserRepository extends CrudRepository<User, String> { public List<User> findByPhone(String phone); public List<User> findByAuthtoken(String authtoken); public List<User> findByPushKey(String pushKey); } UserRepository We need to find by push key in order to remove or update expired push keys. If the server returns an error we need to update that.
  • 21. import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; public class UserDAO { private String id; private String name; private String tagline; private String phone; @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS") private Date creationDate; private String avatar; private String token; public UserDAO() { } public UserDAO(String id, String name, String tagline, String phone, Date creationDate, String avatar) { this.id = id; this.name = name; UserDAO UserDAO is a pretty much the content of the user class, there isn't much to discuss here with one major exception and that’s the JSON format annotation. Here we explicitly declare how we want the Date object to translate to JSON when it’s sent to the client. This is the standard JSON pattern and Codename One in the client side knows how to parse this