const BaaS = require('./baas')
const constants = require('./constants')
const HError = require('./HError')
const storageAsync = require('./storageAsync')
const utils = require('./utils')
const UserRecord = require('./UserRecord')
const User = require('./User')
/**
* 用户认证
* @namespace auth
* @memberof BaaS
*/
const API = BaaS._config.API
function getAuthUrl(data, isLoginFunc) {
if (data.phone) {
return isLoginFunc ? API.LOGIN_PHONE : API.REGISTER_PHONE
}
if (data.email) {
return isLoginFunc ? API.LOGIN_EMAIL : API.REGISTER_EMAIL
}
return isLoginFunc ? API.LOGIN_USERNAME : API.REGISTER_USERNAME
}
function getAuthRequestData(data) {
if (data.phone) {
return {
phone: data.phone,
password: data.password,
}
}
if (data.email) {
return {
email: data.email,
password: data.password,
}
}
return {
username: data.username || '',
password: data.password,
}
}
/**
* 登录
* @since v2.0.0
* @memberof BaaS.auth
* @param {(BaaS.AuthWithUsernameOptions|BaaS.AuthWithEmailOptions|BaaS.AuthWithPhoneOptions)} options
* @return {Promise<BaaS.CurrentUser>}
*/
const login = params => {
let url = getAuthUrl(params, true)
let data = getAuthRequestData(params)
return BaaS.request({
url,
method: 'POST',
data,
}).then(utils.validateStatusCode).then(res => {
BaaS._polyfill.handleLoginSuccess(res)
return getCurrentUser()
})
}
/**
* 匿名登录
* @since v2.0.0
* @memberof BaaS.auth
* @return {Promise<BaaS.CurrentUser>}
*/
const anonymousLogin = () => {
return BaaS.request({
url: API.ANONYMOUS_LOGIN,
method: 'POST',
}).then(utils.validateStatusCode).then(res => {
BaaS._polyfill.handleLoginSuccess(res, true)
return getCurrentUser()
})
}
/**
* 静默登录
* @since v2.0.0
* @memberof BaaS.auth
* @return {Promise<BaaS.CurrentUser>}
*/
const silentLogin = () => {
return Promise.reject(new HError(605, 'silentLogin 方法未定义'))
}
/**
* 注册
* @since v2.0.0
* @memberof BaaS.auth
* @param {(BaaS.AuthWithUsernameOptions|BaaS.AuthWithEmailOptions|BaaS.AuthWithPhoneOptions)} options
* @return {Promise<BaaS.CurrentUser>}
*/
const register = params => {
let url = getAuthUrl(params)
let data = getAuthRequestData(params)
return BaaS.request({
url,
method: 'POST',
data,
}).then(utils.validateStatusCode).then(res => {
BaaS._polyfill.handleLoginSuccess(res)
return getCurrentUser()
})
}
/**
* 退出登录状态
* @since v2.0.0
* @memberof BaaS.auth
* @return {Promise<BaaS.Response<any>>}
*/
const logout = () => {
return BaaS.request({
url: API.LOGOUT,
method: 'POST',
}).then(utils.validateStatusCode).then(res => {
return BaaS.clearSession().then(() => res)
})
}
/**
* 忘记密码,发送重置密码邮件
* @since v2.0.0
* @memberof BaaS.auth
* @param {BaaS.PasswordResetParam} param 账号信息
* @return {Promise<BaaS.Response<any>>}
*/
const requestPasswordReset = ({email} = {}) => {
return BaaS.request({
url: API.PASSWORD_RESET,
method: 'POST',
data: {email},
}).then(utils.validateStatusCode)
}
const _initCurrentUser = (userInfo, session_expires_at) => {
let user = UserRecord.initCurrentUser(userInfo)
user.user_id = userInfo.id
user.session_expires_at = session_expires_at
return user
}
/**
* 获取当前用户
* @since v2.0.0
* @memberof BaaS.auth
* @return {Promise<BaaS.CurrentUser>}
*/
let getCurrentUser = () => {
return Promise.all([
storageAsync.get(constants.STORAGE_KEY.UID),
storageAsync.get(constants.STORAGE_KEY.EXPIRES_AT),
utils.isSessionExpired(),
]).then(([uid, expiresAt, expired]) => {
if (!uid || !expiresAt || expired) return Promise.reject(new HError(604))
return new User().get(uid).then(res => {
return _initCurrentUser(res.data, expiresAt)
})
})
}
/**
* 使用手机号 + 验证码登录
* @since v2.0.0
* @memberof BaaS.auth
* @param {string} mobilePhone 手机号码
* @param {string} smsCode 验证码
* @param {BaaS.LoginOptions} [options] 可选配置
* @return {Promise<BaaS.CurrentUser>}
*/
const loginWithSmsVerificationCode = (mobilePhone, smsCode, {createUser = true} = {}) => {
return BaaS.request({
url: API.LOGIN_SMS,
data: {phone: mobilePhone, code: smsCode, create_user: createUser},
method: 'POST',
}).then(utils.validateStatusCode).then(res => {
BaaS._polyfill.handleLoginSuccess(res, false)
return getCurrentUser()
})
}
module.exports = {
login: utils.rateLimit(login),
logout,
silentLogin,
loginWithSmsVerificationCode: utils.rateLimit(loginWithSmsVerificationCode),
anonymousLogin: utils.rateLimit(anonymousLogin),
requestPasswordReset,
register: utils.rateLimit(register),
_initCurrentUser,
getCurrentUser: utils.rateLimit(getCurrentUser),
}