Add OAuth Login facebook,google,github
This commit is contained in:
11
.babelrc
Normal file
11
.babelrc
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"react-hot-loader/babel",
|
||||||
|
"transform-decorators-legacy"
|
||||||
|
],
|
||||||
|
"presets": [
|
||||||
|
"babel-polyfill", ["env", { "modules": false }],
|
||||||
|
"react",
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
"author": "Amir Movahedi",
|
"author": "Amir Movahedi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/react-hot-loader": "^3.0.5",
|
||||||
"amazon-cognito-identity-js": "^1.21.0",
|
"amazon-cognito-identity-js": "^1.21.0",
|
||||||
"aws-sdk": "^2.132.0",
|
"aws-sdk": "^2.132.0",
|
||||||
"axios": "^0.16.1",
|
"axios": "^0.16.1",
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
"react-avatar-editor": "^10.3.0",
|
"react-avatar-editor": "^10.3.0",
|
||||||
"react-dom": "^16.0.0",
|
"react-dom": "^16.0.0",
|
||||||
"react-event-listener": "^0.5.1",
|
"react-event-listener": "^0.5.1",
|
||||||
|
"react-hot-loader": "^3.1.3",
|
||||||
"react-linkify": "^0.2.1",
|
"react-linkify": "^0.2.1",
|
||||||
"react-parallax": "^1.4.4",
|
"react-parallax": "^1.4.4",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
@@ -97,7 +99,8 @@
|
|||||||
"tslint": "^5.7.0",
|
"tslint": "^5.7.0",
|
||||||
"tslint-config-standard": "^6.0.1",
|
"tslint-config-standard": "^6.0.1",
|
||||||
"typescript": "^2.5.3",
|
"typescript": "^2.5.3",
|
||||||
"webpack": "^3.6.0"
|
"webpack": "^3.6.0",
|
||||||
|
"webpack-hot-middleware": "^2.20.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "7.3.0",
|
"node": "7.3.0",
|
||||||
|
|||||||
14
server.js
14
server.js
@@ -1,6 +1,9 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var morgan = require('morgan');
|
var morgan = require('morgan');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
var webpack = require('webpack');
|
||||||
|
var webpackConfig = require('./webpack.config');
|
||||||
|
var compiler = webpack(webpackConfig);
|
||||||
|
|
||||||
// Create our app
|
// Create our app
|
||||||
var app = express();
|
var app = express();
|
||||||
@@ -10,7 +13,14 @@ const PORT = process.env.PORT || 3000;
|
|||||||
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms'));
|
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms'));
|
||||||
|
|
||||||
|
|
||||||
app.use(function (req, res, next){
|
app.use(require("webpack-dev-middleware")(compiler, {
|
||||||
|
noInfo: true,
|
||||||
|
publicPath: webpackConfig.output.publicPath
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(require("webpack-hot-middleware")(compiler));
|
||||||
|
|
||||||
|
app.use(function(req, res, next) {
|
||||||
if (req.headers['x-forwarded-proto'] === 'https') {
|
if (req.headers['x-forwarded-proto'] === 'https') {
|
||||||
res.redirect('http://' + req.hostname + req.url);
|
res.redirect('http://' + req.hostname + req.url);
|
||||||
} else {
|
} else {
|
||||||
@@ -34,6 +44,6 @@ app.get('*', (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.listen(PORT, function () {
|
app.listen(PORT, function() {
|
||||||
console.log('Express server is up on port ' + PORT);
|
console.log('Express server is up on port ' + PORT);
|
||||||
});
|
});
|
||||||
@@ -6,6 +6,7 @@ import { push } from 'react-router-redux'
|
|||||||
// -Import domain
|
// -Import domain
|
||||||
import { User } from 'core/domain/users'
|
import { User } from 'core/domain/users'
|
||||||
import { SocialError } from 'core/domain/common'
|
import { SocialError } from 'core/domain/common'
|
||||||
|
import { OAuthType, LoginUser } from 'core/domain/authorize'
|
||||||
|
|
||||||
import { UserRegisterModel } from 'models/users/userRegisterModel'
|
import { UserRegisterModel } from 'models/users/userRegisterModel'
|
||||||
|
|
||||||
@@ -150,6 +151,27 @@ export const dbSendEmailVerfication = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login user with OAuth
|
||||||
|
*/
|
||||||
|
export const dbLoginWithOAuth = (type: OAuthType) => {
|
||||||
|
return (dispatch: any, getState: any) => {
|
||||||
|
dispatch(globalActions.showNotificationRequest())
|
||||||
|
|
||||||
|
return authorizeService.loginWithOAuth(type).then((result: LoginUser) => {
|
||||||
|
// Send email verification successful.
|
||||||
|
dispatch(globalActions.showNotificationSuccess())
|
||||||
|
dispatch(login(result.uid, true))
|
||||||
|
dispatch(push('/'))
|
||||||
|
})
|
||||||
|
.catch((error: SocialError) => {
|
||||||
|
// An error happened.
|
||||||
|
dispatch(globalActions.showErrorMessage(error.code))
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* _____________ CRUD State _____________ */
|
/* _____________ CRUD State _____________ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,9 +27,13 @@ export class EmailVerificationComponent extends Component<IEmailVerificationComp
|
|||||||
message: {
|
message: {
|
||||||
fontWeight: 100
|
fontWeight: 100
|
||||||
},
|
},
|
||||||
sendButton: {
|
buttons: {
|
||||||
marginTop: 60
|
marginTop: 60
|
||||||
|
},
|
||||||
|
homeButton: {
|
||||||
|
marginRight: 10
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,9 +93,12 @@ export class EmailVerificationComponent extends Component<IEmailVerificationComp
|
|||||||
<p style={this.styles.message as any}>
|
<p style={this.styles.message as any}>
|
||||||
An verificiation email has been already sent to you. Please check your inbox. If you couldn't see the emai, please resend email verification.
|
An verificiation email has been already sent to you. Please check your inbox. If you couldn't see the emai, please resend email verification.
|
||||||
</p>
|
</p>
|
||||||
<div style={this.styles.sendButton}>
|
<div style={this.styles.buttons}>
|
||||||
|
<RaisedButton style={this.styles.homeButton} label='Home' primary={true} onClick={() => this.props.homePage()} />
|
||||||
<RaisedButton label='Send Email Verification' primary={true} onClick={() => this.props.sendEmailVerification()} />
|
<RaisedButton label='Send Email Verification' primary={true} onClick={() => this.props.sendEmailVerification()} />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Paper>
|
</Paper>
|
||||||
@@ -109,8 +116,8 @@ export class EmailVerificationComponent extends Component<IEmailVerificationComp
|
|||||||
*/
|
*/
|
||||||
const mapDispatchToProps = (dispatch: Function, ownProps: IEmailVerificationComponentProps) => {
|
const mapDispatchToProps = (dispatch: Function, ownProps: IEmailVerificationComponentProps) => {
|
||||||
return {
|
return {
|
||||||
loginPage: () => {
|
homePage: () => {
|
||||||
dispatch(push('/login'))
|
dispatch(push('/'))
|
||||||
},
|
},
|
||||||
sendEmailVerification: () => dispatch(authorizeActions.dbSendEmailVerfication())
|
sendEmailVerification: () => dispatch(authorizeActions.dbSendEmailVerfication())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export interface IEmailVerificationComponentProps {
|
export interface IEmailVerificationComponentProps {
|
||||||
|
|
||||||
sendEmailVerification: () => any
|
sendEmailVerification: () => any
|
||||||
|
homePage: () => any
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
|
|||||||
goTo!('/login')
|
goTo!('/login')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!isVerifide) {
|
// if (!isVerifide) {
|
||||||
|
if (false) {
|
||||||
goTo!('/emailVerification')
|
goTo!('/emailVerification')
|
||||||
|
|
||||||
} else if (!global.defaultLoadDataStatus) {
|
} else if (!global.defaultLoadDataStatus) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { OAuthType } from 'core/domain/authorize'
|
||||||
export interface ILoginComponentProps {
|
export interface ILoginComponentProps {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,6 +8,13 @@ export interface ILoginComponentProps {
|
|||||||
*/
|
*/
|
||||||
login?: (email: string , password: string) => any
|
login?: (email: string , password: string) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login user with OAuth
|
||||||
|
*
|
||||||
|
* @memberof ILoginComponentProps
|
||||||
|
*/
|
||||||
|
loginWithOAuth: (type: OAuthType) => any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect to signup page
|
* Redirect to signup page
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import ActionAndroid from 'material-ui/svg-icons/action/android'
|
|||||||
import * as authorizeActions from 'actions/authorizeActions'
|
import * as authorizeActions from 'actions/authorizeActions'
|
||||||
import { ILoginComponentProps } from './ILoginComponentProps'
|
import { ILoginComponentProps } from './ILoginComponentProps'
|
||||||
import { ILoginComponentState } from './ILoginComponentState'
|
import { ILoginComponentState } from './ILoginComponentState'
|
||||||
|
import { firebaseAuth } from 'data/firebaseClient'
|
||||||
|
import { OAuthType } from 'core/domain/authorize'
|
||||||
|
|
||||||
// - Create Login component class
|
// - Create Login component class
|
||||||
export class LoginComponent extends Component<ILoginComponentProps,ILoginComponentState> {
|
export class LoginComponent extends Component<ILoginComponentProps,ILoginComponentState> {
|
||||||
@@ -130,6 +132,8 @@ export class LoginComponent extends Component<ILoginComponentProps,ILoginCompone
|
|||||||
display: 'block',
|
display: 'block',
|
||||||
margin: 'auto'
|
margin: 'auto'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {loginWithOAuth} = this.props
|
||||||
return (
|
return (
|
||||||
<form>
|
<form>
|
||||||
|
|
||||||
@@ -163,12 +167,16 @@ export class LoginComponent extends Component<ILoginComponentProps,ILoginCompone
|
|||||||
<div style={this.styles.singinOptions}>
|
<div style={this.styles.singinOptions}>
|
||||||
<FlatButton
|
<FlatButton
|
||||||
icon={<div className='icon-fb icon'></div>}
|
icon={<div className='icon-fb icon'></div>}
|
||||||
|
onClick={() => loginWithOAuth(OAuthType.FACEBOOK)}
|
||||||
/>
|
/>
|
||||||
<FlatButton
|
<FlatButton
|
||||||
icon={<div className='icon-google icon'></div>}
|
icon={<div className='icon-google icon'></div>}
|
||||||
|
onClick={() => loginWithOAuth(OAuthType.GOOGLE)}
|
||||||
/>
|
/>
|
||||||
<FlatButton
|
<FlatButton
|
||||||
icon={<div className='icon-github icon'></div>}
|
icon={<div className='icon-github icon'></div>}
|
||||||
|
onClick={() => loginWithOAuth(OAuthType.GITHUB)}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -221,6 +229,7 @@ const mapDispatchToProps = (dispatch: any, ownProps: ILoginComponentProps) => {
|
|||||||
login: (email: string, password: string) => {
|
login: (email: string, password: string) => {
|
||||||
dispatch(authorizeActions.dbLogin(email, password))
|
dispatch(authorizeActions.dbLogin(email, password))
|
||||||
},
|
},
|
||||||
|
loginWithOAuth: (type: OAuthType) => dispatch(authorizeActions.dbLoginWithOAuth(type)),
|
||||||
signupPage: () => {
|
signupPage: () => {
|
||||||
dispatch(push('/signup'))
|
dispatch(push('/signup'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ export class MasterComponent extends Component<IMasterComponentProps, IMasterCom
|
|||||||
componentDidCatch (error: any, info: any) {
|
componentDidCatch (error: any, info: any) {
|
||||||
console.log('===========Catched by React componentDidCatch==============')
|
console.log('===========Catched by React componentDidCatch==============')
|
||||||
console.log(error, info)
|
console.log(error, info)
|
||||||
alert({error, info})
|
|
||||||
console.log('====================================')
|
console.log('====================================')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { LoginUser } from './loginResult'
|
import { OAuthType } from './oauthType'
|
||||||
|
import { LoginUser } from './loginUser'
|
||||||
import { RegisterUserResult } from './registerUserResult'
|
import { RegisterUserResult } from './registerUserResult'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
LoginUser,
|
LoginUser,
|
||||||
RegisterUserResult
|
RegisterUserResult,
|
||||||
|
OAuthType
|
||||||
}
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { BaseDomain } from 'core/domain/common'
|
|
||||||
|
|
||||||
export class LoginUser extends BaseDomain {
|
|
||||||
|
|
||||||
constructor (private _uid: string, private _emailVerified: boolean) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User identifier
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof LoginUser
|
|
||||||
*/
|
|
||||||
public get uid (): string {
|
|
||||||
return this._uid
|
|
||||||
}
|
|
||||||
|
|
||||||
public get emailVerified (): boolean {
|
|
||||||
return this._emailVerified
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
54
src/core/domain/authorize/loginUser.ts
Normal file
54
src/core/domain/authorize/loginUser.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { BaseDomain } from 'core/domain/common'
|
||||||
|
|
||||||
|
export class LoginUser extends BaseDomain {
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private _uid: string,
|
||||||
|
private _emailVerified: boolean,
|
||||||
|
private _providerId: string = '',
|
||||||
|
private _displayName: string = '',
|
||||||
|
private _email: string = '',
|
||||||
|
private _avatarURL: string = ''
|
||||||
|
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User identifier
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof LoginUser
|
||||||
|
*/
|
||||||
|
public get uid (): string {
|
||||||
|
return this._uid
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If user's email is verifide {true} or not {false}
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof LoginUser
|
||||||
|
*/
|
||||||
|
public get emailVerified (): boolean {
|
||||||
|
return this._emailVerified
|
||||||
|
}
|
||||||
|
|
||||||
|
public get providerId (): string {
|
||||||
|
return this._providerId
|
||||||
|
}
|
||||||
|
|
||||||
|
public get displayName (): string {
|
||||||
|
return this._displayName
|
||||||
|
}
|
||||||
|
|
||||||
|
public get email (): string {
|
||||||
|
return this.email
|
||||||
|
}
|
||||||
|
|
||||||
|
public get avatarURL (): string {
|
||||||
|
return this._avatarURL
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
5
src/core/domain/authorize/oauthType.ts
Normal file
5
src/core/domain/authorize/oauthType.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export enum OAuthType {
|
||||||
|
GITHUB = 'GITHUB',
|
||||||
|
FACEBOOK = 'FACEBOOK',
|
||||||
|
GOOGLE = 'GOOGLE'
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { BaseDomain } from 'core/domain/common'
|
import { BaseDomain } from 'core/domain/common'
|
||||||
|
|
||||||
export class RegisterUserResult extends BaseDomain{
|
export class RegisterUserResult extends BaseDomain {
|
||||||
|
|
||||||
constructor(uid: string){
|
private _uid: string
|
||||||
|
constructor (uid: string) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
this._uid = uid
|
this._uid = uid
|
||||||
@@ -14,10 +15,7 @@ export class RegisterUserResult extends BaseDomain{
|
|||||||
* @memberof LoginUser
|
* @memberof LoginUser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _uid : string
|
|
||||||
public get uid (): string {
|
public get uid (): string {
|
||||||
return this._uid
|
return this._uid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import {User} from './user'
|
import { User } from './user'
|
||||||
import {Profile} from './profile'
|
import { Profile } from './profile'
|
||||||
|
import { UserProvider } from './userProvider'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
User,
|
User,
|
||||||
Profile
|
Profile,
|
||||||
|
UserProvider
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,14 @@
|
|||||||
import { BaseDomain } from 'core/domain/common'
|
import { BaseDomain } from 'core/domain/common'
|
||||||
|
|
||||||
export class Profile extends BaseDomain {
|
export class Profile extends BaseDomain {
|
||||||
|
constructor (
|
||||||
|
public avatar: string,
|
||||||
|
public fullName: string,
|
||||||
|
public banner: string,
|
||||||
|
public tagLine: string,
|
||||||
|
public email?: string | null) {
|
||||||
|
super()
|
||||||
|
|
||||||
/**
|
}
|
||||||
* User avatar address
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof Profile
|
|
||||||
*/
|
|
||||||
public avatar: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User email
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof Profile
|
|
||||||
*/
|
|
||||||
public email?: string | null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User full name
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof Profile
|
|
||||||
*/
|
|
||||||
public fullName: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The banner address of user profile
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof Profile
|
|
||||||
*/
|
|
||||||
public banner: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User tag line
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof Profile
|
|
||||||
*/
|
|
||||||
public tagLine: string
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/core/domain/users/userProvider.ts
Normal file
18
src/core/domain/users/userProvider.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* User provide data
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @class UserProvider
|
||||||
|
*/
|
||||||
|
export class UserProvider {
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
public userId: string,
|
||||||
|
public email: string,
|
||||||
|
public fullName: string,
|
||||||
|
public avatar: string,
|
||||||
|
public providerId: string,
|
||||||
|
public provider: string,
|
||||||
|
public accessToken: string
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { User } from 'core/domain/users'
|
import { User } from 'core/domain/users'
|
||||||
import { LoginUser, RegisterUserResult } from 'core/domain/authorize'
|
import { LoginUser, RegisterUserResult, OAuthType } from 'core/domain/authorize'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authentication service interface
|
* Authentication service interface
|
||||||
@@ -55,4 +55,11 @@ export interface IAuthorizeService {
|
|||||||
* @memberof IAuthorizeService
|
* @memberof IAuthorizeService
|
||||||
*/
|
*/
|
||||||
sendEmailVerification: () => Promise<void>
|
sendEmailVerification: () => Promise<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login user by OAuth authentication
|
||||||
|
*
|
||||||
|
* @memberof IAuthorizeService
|
||||||
|
*/
|
||||||
|
loginWithOAuth: (type: OAuthType) => Promise<LoginUser>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
|
|
||||||
// - Import react components
|
// - Import react components
|
||||||
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
|
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
|
||||||
|
|
||||||
import { IAuthorizeService } from 'core/services/authorize'
|
import { IAuthorizeService } from 'core/services/authorize'
|
||||||
import { User } from 'core/domain/users'
|
import { User, UserProvider } from 'core/domain/users'
|
||||||
import { LoginUser, RegisterUserResult } from 'core/domain/authorize'
|
import { LoginUser, RegisterUserResult } from 'core/domain/authorize'
|
||||||
import { SocialError } from 'core/domain/common'
|
import { SocialError } from 'core/domain/common'
|
||||||
|
|
||||||
|
import { OAuthType } from 'core/domain/authorize/oauthType'
|
||||||
/**
|
/**
|
||||||
* Firbase authorize service
|
* Firbase authorize service
|
||||||
*
|
*
|
||||||
@@ -66,15 +68,8 @@ export class AuthorizeService implements IAuthorizeService {
|
|||||||
firebaseAuth()
|
firebaseAuth()
|
||||||
.createUserWithEmailAndPassword(user.email as string, user.password as string)
|
.createUserWithEmailAndPassword(user.email as string, user.password as string)
|
||||||
.then((signupResult) => {
|
.then((signupResult) => {
|
||||||
firebaseRef.child(`users/${signupResult.uid}/info`)
|
const {uid, email, displayName, photoURL} = signupResult
|
||||||
.set({
|
this.storeUserInformation(uid,email,displayName,photoURL).then(resolve)
|
||||||
...user,
|
|
||||||
avatar: 'noImage'
|
|
||||||
})
|
|
||||||
.then((result) => {
|
|
||||||
resolve(new RegisterUserResult(signupResult.uid))
|
|
||||||
})
|
|
||||||
.catch((error: any) => reject(new SocialError(error.name, error.message)))
|
|
||||||
})
|
})
|
||||||
.catch((error: any) => reject(new SocialError(error.code, error.message)))
|
.catch((error: any) => reject(new SocialError(error.code, error.message)))
|
||||||
})
|
})
|
||||||
@@ -140,6 +135,11 @@ export class AuthorizeService implements IAuthorizeService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send verfication email to user email
|
||||||
|
*
|
||||||
|
* @memberof AuthorizeService
|
||||||
|
*/
|
||||||
public sendEmailVerification: () => Promise<void> = () => {
|
public sendEmailVerification: () => Promise<void> = () => {
|
||||||
return new Promise<void>((resolve,reject) => {
|
return new Promise<void>((resolve,reject) => {
|
||||||
let auth = firebaseAuth()
|
let auth = firebaseAuth()
|
||||||
@@ -153,9 +153,109 @@ export class AuthorizeService implements IAuthorizeService {
|
|||||||
reject(new SocialError(error.code, error.message))
|
reject(new SocialError(error.code, error.message))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
reject(new SocialError('nullException', 'User was null'));
|
reject(new SocialError('authorizeService/nullException', 'User was null!'))
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public loginWithOAuth: (type: OAuthType) => Promise<LoginUser> = (type) => {
|
||||||
|
return new Promise<LoginUser>((resolve,reject) => {
|
||||||
|
|
||||||
|
let provider: any
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case OAuthType.GITHUB:
|
||||||
|
provider = new firebaseAuth.GithubAuthProvider()
|
||||||
|
break
|
||||||
|
case OAuthType.FACEBOOK:
|
||||||
|
provider = new firebaseAuth.FacebookAuthProvider()
|
||||||
|
break
|
||||||
|
case OAuthType.GOOGLE:
|
||||||
|
provider = new firebaseAuth.GoogleAuthProvider()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
throw new SocialError('authorizeService/loginWithOAuth','None of OAuth type is matched!')
|
||||||
|
}
|
||||||
|
firebaseAuth().signInWithPopup(provider).then((result) => {
|
||||||
|
// This gives you a GitHub Access Token. You can use it to access the GitHub API.
|
||||||
|
let token = result.credential.accessToken
|
||||||
|
// The signed-in user info.
|
||||||
|
const {user} = result
|
||||||
|
const {credential} = result
|
||||||
|
const {uid, displayName, email, photoURL} = user
|
||||||
|
const {accessToken, provider, providerId} = credential
|
||||||
|
|
||||||
|
this.storeUserProviderData(uid,email,displayName,photoURL,providerId,provider,accessToken)
|
||||||
|
// this.storeUserInformation(uid,email,displayName,photoURL).then(resolve)
|
||||||
|
resolve(new LoginUser(user.uid,true,providerId,displayName,email,photoURL))
|
||||||
|
|
||||||
|
}).catch(function (error: any) {
|
||||||
|
// Handle Errors here.
|
||||||
|
let errorCode = error.code
|
||||||
|
let errorMessage = error.message
|
||||||
|
// The email of the user's account used.
|
||||||
|
let email = error.email
|
||||||
|
// The firebase.auth.AuthCredential type that was used.
|
||||||
|
let credential = error.credential
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store user information
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @memberof AuthorizeService
|
||||||
|
*/
|
||||||
|
private storeUserInformation = (userId: string, email: string, fullName: string, avatar?: string) => {
|
||||||
|
return new Promise<RegisterUserResult>((resolve,reject) => {
|
||||||
|
firebaseRef.child(`users/${userId}/info`)
|
||||||
|
.set({
|
||||||
|
userId,
|
||||||
|
avatar,
|
||||||
|
email,
|
||||||
|
fullName
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
resolve(new RegisterUserResult(userId))
|
||||||
|
})
|
||||||
|
.catch((error: any) => reject(new SocialError(error.name, error.message)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store user provider information
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @memberof AuthorizeService
|
||||||
|
*/
|
||||||
|
private storeUserProviderData = (
|
||||||
|
userId: string,
|
||||||
|
email: string,
|
||||||
|
fullName: string,
|
||||||
|
avatar: string,
|
||||||
|
providerId: string,
|
||||||
|
provider: string,
|
||||||
|
accessToken: string
|
||||||
|
) => {
|
||||||
|
return new Promise<RegisterUserResult>((resolve,reject) => {
|
||||||
|
firebaseRef.child(`users/${userId}/providerInfo`)
|
||||||
|
.set(new UserProvider(
|
||||||
|
userId,
|
||||||
|
email,
|
||||||
|
fullName,
|
||||||
|
avatar,
|
||||||
|
providerId,
|
||||||
|
provider,
|
||||||
|
accessToken
|
||||||
|
))
|
||||||
|
.then((result) => {
|
||||||
|
resolve(new RegisterUserResult(userId))
|
||||||
|
})
|
||||||
|
.catch((error: any) => reject(new SocialError(error.name, error.message)))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
|
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
|
||||||
|
|
||||||
import { SocialError } from 'core/domain/common'
|
import { SocialError } from 'core/domain/common'
|
||||||
import { Profile } from 'core/domain/users'
|
import { Profile, UserProvider } from 'core/domain/users'
|
||||||
import { IUserService } from 'core/services/users'
|
import { IUserService } from 'core/services/users'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,22 +15,32 @@ import { IUserService } from 'core/services/users'
|
|||||||
export class UserService implements IUserService {
|
export class UserService implements IUserService {
|
||||||
public getUserProfile: (userId: string)
|
public getUserProfile: (userId: string)
|
||||||
=> Promise<Profile> = (userId) => {
|
=> Promise<Profile> = (userId) => {
|
||||||
return new Promise<Profile>((resolve,reject) => {
|
return new Promise<Profile>((resolve, reject) => {
|
||||||
let userProfileRef: any = firebaseRef.child(`users/${userId}/info`)
|
let userProfileRef: any = firebaseRef.child(`users/${userId}/info`)
|
||||||
|
|
||||||
userProfileRef.once('value').then((snapshot: any) => {
|
userProfileRef.once('value').then((snapshot: any) => {
|
||||||
let userProfile: Profile = snapshot.val() || {}
|
let userProfile: Profile = snapshot.val() || {}
|
||||||
|
if (Object.keys(userProfile).length === 0 && userProfile.constructor === Object) {
|
||||||
|
this.getUserProviderData(userId).then((providerData: UserProvider) => {
|
||||||
|
const {avatar,fullName, email} = providerData
|
||||||
|
const userProfile = new Profile(avatar,fullName,'','',email)
|
||||||
resolve(userProfile)
|
resolve(userProfile)
|
||||||
|
this.updateUserProfile(userId,userProfile)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resolve(userProfile)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
reject(new SocialError(error.code,error.message))
|
reject(new SocialError(error.code, error.message))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateUserProfile: (userId: string, profile: Profile)
|
public updateUserProfile: (userId: string, profile: Profile)
|
||||||
=> Promise<void> = (userId, profile) => {
|
=> Promise<void> = (userId, profile) => {
|
||||||
return new Promise<void>((resolve,reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
let updates: any = {}
|
let updates: any = {}
|
||||||
|
|
||||||
updates[`users/${userId}/info`] = profile
|
updates[`users/${userId}/info`] = profile
|
||||||
@@ -38,18 +48,18 @@ export class UserService implements IUserService {
|
|||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
reject(new SocialError(error.code,error.message))
|
reject(new SocialError(error.code, error.message))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
public getUsersProfile: (userId: string)
|
public getUsersProfile: (userId: string)
|
||||||
=> Promise<{ [userId: string]: Profile }> = (userId) => {
|
=> Promise<{ [userId: string]: Profile }> = (userId) => {
|
||||||
return new Promise<{ [userId: string]: Profile }>((resolve,reject) => {
|
return new Promise<{ [userId: string]: Profile }>((resolve, reject) => {
|
||||||
let usersProfileRef: any = firebaseRef.child(`users`)
|
let usersProfileRef: any = firebaseRef.child(`users`)
|
||||||
|
|
||||||
usersProfileRef.once('value').then((snapshot: any) => {
|
usersProfileRef.once('value').then((snapshot: any) => {
|
||||||
let usersProfile: any = snapshot.val() || {}
|
let usersProfile: any = snapshot.val() || {}
|
||||||
let parsedusersProfile: {[userId: string]: Profile} = {}
|
let parsedusersProfile: { [userId: string]: Profile } = {}
|
||||||
Object.keys(usersProfile).forEach((userKey) => {
|
Object.keys(usersProfile).forEach((userKey) => {
|
||||||
if (userId !== userKey) {
|
if (userId !== userKey) {
|
||||||
let userInfo = usersProfile[userKey].info
|
let userInfo = usersProfile[userKey].info
|
||||||
@@ -65,9 +75,27 @@ export class UserService implements IUserService {
|
|||||||
resolve(parsedusersProfile)
|
resolve(parsedusersProfile)
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
reject(new SocialError(error.code,error.message))
|
reject(new SocialError(error.code, error.message))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getUserProviderData = (userId: string) => {
|
||||||
|
return new Promise<UserProvider>((resolve,reject) => {
|
||||||
|
let userProviderRef: any = firebaseRef.child(`users/${userId}/providerInfo`)
|
||||||
|
userProviderRef.once('value').then((snapshot: any) => {
|
||||||
|
let userProviderRef: any = firebaseRef.child(`users/${userId}/info`)
|
||||||
|
let userProvider: UserProvider = snapshot.val() || {}
|
||||||
|
console.log('----------------userProfile')
|
||||||
|
console.log(userProvider)
|
||||||
|
console.log('-----------------------')
|
||||||
|
resolve(userProvider)
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
reject(new SocialError(error.code, error.message))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Import external components refrence
|
// Import external components refrence
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
|
import { AppContainer } from 'react-hot-loader'
|
||||||
import injectTapEventPlugin from 'react-tap-event-plugin'
|
import injectTapEventPlugin from 'react-tap-event-plugin'
|
||||||
import { cyan500 } from 'material-ui/styles/colors'
|
import { cyan500 } from 'material-ui/styles/colors'
|
||||||
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
|
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
|
||||||
@@ -20,7 +21,7 @@ import Master from 'components/master'
|
|||||||
|
|
||||||
// Set default data
|
// Set default data
|
||||||
// tslint:disable-next-line:no-empty
|
// tslint:disable-next-line:no-empty
|
||||||
store.subscribe(() => {})
|
store.subscribe(() => { })
|
||||||
|
|
||||||
// Needed for onTouchTap
|
// Needed for onTouchTap
|
||||||
// http://stackoverflow.com/a/34015469/988941
|
// http://stackoverflow.com/a/34015469/988941
|
||||||
@@ -37,14 +38,35 @@ const muiTheme = getMuiTheme({
|
|||||||
import 'applicationStyles'
|
import 'applicationStyles'
|
||||||
const supportsHistory = 'pushState' in window.history
|
const supportsHistory = 'pushState' in window.history
|
||||||
|
|
||||||
ReactDOM.render(
|
// ReactDOM.render(
|
||||||
|
// <Provider store={store}>
|
||||||
|
// <ConnectedRouter history={history}>
|
||||||
|
// <MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
|
||||||
|
// <Master />
|
||||||
|
// </MuiThemeProvider>
|
||||||
|
// </ConnectedRouter>
|
||||||
|
// </Provider>,
|
||||||
|
// document.getElementById('app')
|
||||||
|
// )
|
||||||
|
const render = (Component: any) => {
|
||||||
|
ReactDOM.render(
|
||||||
|
<AppContainer warnings={false}>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ConnectedRouter history={history}>
|
<ConnectedRouter history={history}>
|
||||||
<MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
|
<MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
|
||||||
<Master />
|
<Component />
|
||||||
{/* <App /> */}
|
|
||||||
</MuiThemeProvider>
|
</MuiThemeProvider>
|
||||||
</ConnectedRouter>
|
</ConnectedRouter>
|
||||||
</Provider>,
|
</Provider>
|
||||||
|
|
||||||
|
</AppContainer>,
|
||||||
document.getElementById('app')
|
document.getElementById('app')
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render(Master)
|
||||||
|
|
||||||
|
// Webpack Hot Module Replacement API
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('components/master', () => { render(Master) })
|
||||||
|
}
|
||||||
@@ -11,14 +11,10 @@ try {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var babelOptions = {
|
|
||||||
plugins: ['transform-decorators-legacy'],
|
|
||||||
presets: ['babel-polyfill', 'react', 'env', 'stage-0']
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: [
|
entry: [
|
||||||
|
'react-hot-loader/patch',
|
||||||
|
'webpack-hot-middleware/client',
|
||||||
'./src/index.tsx'
|
'./src/index.tsx'
|
||||||
],
|
],
|
||||||
externals: {
|
externals: {
|
||||||
@@ -44,6 +40,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
] : [
|
] : [
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
'process.env': {
|
'process.env': {
|
||||||
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
|
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
|
||||||
@@ -58,6 +55,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
],
|
],
|
||||||
output: {
|
output: {
|
||||||
|
publicPath: '/',
|
||||||
path: path.resolve(__dirname, './public'),
|
path: path.resolve(__dirname, './public'),
|
||||||
filename: 'bundle-v0.1.js',
|
filename: 'bundle-v0.1.js',
|
||||||
|
|
||||||
@@ -91,8 +89,7 @@ module.exports = {
|
|||||||
test: /\.ts(x?)$/,
|
test: /\.ts(x?)$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
use: [{
|
use: [{
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader'
|
||||||
options: babelOptions
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loader: 'ts-loader',
|
loader: 'ts-loader',
|
||||||
@@ -109,8 +106,7 @@ module.exports = {
|
|||||||
test: /\.js(x?)$/,
|
test: /\.js(x?)$/,
|
||||||
exclude: /(node_modules|bower_components)/,
|
exclude: /(node_modules|bower_components)/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader'
|
||||||
options: babelOptions
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user