# App登入、登出
## 取用token、IV
Request:
```javascript
GET /login/secret
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": {
"IV": "wicckmuh@wistron",
"Key": "wicckmuh.wistron"
}
}
}
```
## App 登入
Request:
POST /login/app
body:
```javascript
{
"countryCode": "+886",
"account": "A184407779",
"deviceToken": "exJ9GIMMHuI:APA91bGMV77g0pbqg3tSuJ2cbYU7mEs8xA-SbyYN4NsJAY52qJkA2rTtKqifIqzUfDM4mP7edxqC4irIDAcP-IwlLG7gdEt1-ydOAi0shKX9AV7rqKgPiaoJKCx27CMRxoiNQVH7MiAc",
"deviceType": "ANDROID_APP",
"loginType": "kmuh",
"password": "3yrOv6Rh10zk8zAxmxNtqw==\n",
"clearDuplicateLogin": true,
"eulaId": "5b323376-2bdc-4741-a787-d538db86fbff"
}
```
錯誤代碼
100(成功)/101(找不到使用者)/102(角色錯誤)/103(密碼錯誤)/104(重複登入)/105(未同意隱私權)/ 106(首次登入)
res: e.g. Code = 106 (第一次登入)
```javascript
{
"httpCode": 200,
"result": {
"data": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJXaWNjS01VSCIsImFjY291bnRJZCI6IjJhZTI0MWI4LWQ1ZmMtNGNmNy1hZDJkLThlMzE0YmUzZjEyYiIsImFyZWFDb2RlIjoiODU4YjdmYmItM2JhMC00ZDQ5LTk4ODItYzg5M2ExZWYwN2RjIiwibG9naW5UeXBlIjoia211aCIsImRpc3BsYXlOYW1lIjoi5aSp56u66byg6LuK6LuKIiwic3VybmFtZSI6IuWkqeeruum8oOi7iui7iiIsImlzcyI6Ildpc3Ryb24gU1dQQyIsImhvdXNlaG9sZE1lbWJlcklkIjoiNjA3ZjFiMDItZGQzNi00OWEyLWE2MGUtZjEwOWVkMjhiNWVkIiwidGVuYW50SWQiOiI4NThiN2ZiYi0zYmEwLTRkNDktOTg4Mi1jODkzYTFlZjA3ZGMiLCJyb2xlVHlwZSI6IkdFTkVSQUxfUFVCTElDIiwidXNlcklkIjoiRTEzNjQyNzY5OCIsImp0aSI6Ijg1ZjVjYjAzLTdiYjktNGY2MC05ZmYwLWI5Zjk5YmI0Y2MyYiJ9.2sYi53jwlBrBK33mxLHONN_QhwM6CnMNl2tGyQ3b1mo",
"code": 106,
"expireDate": "Fri Mar 05 16:28:46 CST 2021"
}
}
}
```
## App登出
* 登入不需要token,但登出需要token。
Request:
```url=
POST /user/logout/app
```
header
```javascript
{
"header": "{{token}}"
}
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": {
"isSuccess": true
}
}
}
```
## 變更密碼
* 變更密碼必須有token,亦即必須在登入狀態
Request:
```javascript
POST /generalPublic/changePassword
```
header
```javascript
{
"header": "{{token}}"
}
```
Payload:
```javascript
{
"countryCode": "+886",
"phone":"E124692461",
"password": "LoM7aCNhoIHkcO+eoRUlKA=="
}
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": "true"
}
}
```
ErrorMsg:
* A. 密碼重複未變更 PASSWORD_SAME_AS_OLD
```javascript
{
"errorMsg": "SERVICE_ERROR.PASSWORD_SAME_AS_OLD",
"httpCode": 422
}
```
* B. 舊密碼錯誤
```javascript
{
"errorMsg":"SERVICE_ERROR.PASSWORD_ERROR",
"httpCode": 422
}
```
## 重置密碼(Deprecated)
* 已棄用, 改使用忘記密碼流程
* ~~重置密碼走驗證信流程,亦即不必在登入狀態(沒token)~~
* ~~重置密碼改成以生日(yyyyMMdd)當密碼,登入時一樣要要求變更密碼一次~~
Request:
```javascript
{
"account": "C188256154",
"telephone": "09123456789"
}
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": {
"account": "C188256154",
"password": "20210217", // 暫時會給,以後加入簡訊流程建議拿掉
"clearDuplicateLogin": false,
"telephone": "09123456789"
}
}
}
```
ErrorMsg:
* 帳號不存在或者電話不相符
```javascript
{
"errorMsg": "SERVICE_ERROR.ACCOUNT_NOT_EXISTS",
"httpCode": 422
}
```
## App 註冊帳號
* 不必有token
Request:
```javascript
POST /account/register
```
Attribute | Type | IsRequired | Remark
-|-|-|-
idNo | String | N | 身分證字號
birthDate | String | Y | 生日(yyyy-MM-dd)
name | String | Y | 姓名
countryCode | String | Y | 電話國碼, e.g.台灣為+886
telephone | String | Y | 電話
bodyHeight | number | Y | 身高
gender | int | Y | 性別 1:男性/2:女性
address | String | N | 地址
bloodType | String | N | 血型(O/AB/A/B)
email | String | N | email
otp | String | Y | otp, 6位數字
password | String | Y | 密碼, 需加密
waist | int | N | 腰圍
hips | int | N | 臀圍
Payload:
```javascript
{
"idNo": "A120232858",
"birthDate": "2021-02-17",
"name": "陳三洋",
"countryCode": "+886",
"telephone": "0987654321",
"bodyHeight": 166,
"gender": 1,
"address": "高雄市鹽埕區大勇路100號",
"bloodType": "O",
"email": "123@gmail.com",
"otp": "123456",
"password": "LoM7aCNhoIHkcO+eoRUlKA==",
"waist": 90,
"hips": 110
}
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": {
"accountId": "a72ccbc3-947d-467e-914e-3928dad3270e",
"householdMemberId": "153c671d-29d4-48f2-8ef0-a4b8598dd5d2"
}
}
}
```
ErrorMsg:
* 已經存在的手機號碼(同手機號不同名稱時會將舊帳號封存,封存舊帳號尚未完成,會先拋此ErrorMsg)
```javascript
{
"errorMsg": "SERVICE_ERROR.ACCOUNT_TELEPHONE_DUPLICATE",
"httpCode": 422
}
```
* OTP驗證失敗
```javascript
{
"errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
"httpCode": 422
}
```
## App 解除帳號
```javascript
POST /account/unregister
```
### Request
欄位 | 型態 | 必填 | 長度限制 | 預設 | 說明
---|---|---|---|---|---
### Response
欄位 | 型態 | 說明
--- | --- | ---
data|int|解除帳號數量
```javascript
{
"httpCode": 200,
"result": {
"data": 1
}
}
```
## 產生OTP
* 不需token
Request:
```URL
POST /otp/generate
```
Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼
```javascript
{
"countryCode": "+886",
"phone":"0987654321",
"otpType":"REGISTER"
}
```
Response:
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
otp | String | otp, 6位數字, 測試用時顯示, 實際介接SMS發送時不會顯示此欄位
```javascript
{
"httpCode": 200,
"result": {
"data": {
"id": "a72ccbc3-947d-467e-914e-3928dad3270e",
"otp": "123456"
}
}
}
```
ErrorMsg:
```javascript
// 超過重送次數
{
"errorMsg": "SERVICE_ERROR.OTP_EXCEED_RESEND_TIMES",
"httpCode": 422
}
// OTP已過期
{
"errorMsg": "SERVICE_ERROR.OTP_EXPIRED",
"httpCode": 422
}
// OTP驗證失敗
{
"errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
"httpCode": 422
}
```
## 重送OTP
* 不需token
Request:
```URL
POST /otp/resend
```
Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼
```javascript
{
"countryCode": "+886",
"phone":"0987654321",
"otpType":"REGISTER"
}
```
Response:
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
otp | String | otp, 6位數字, 測試用時顯示, 實際介接SMS發送時不會顯示此欄位
```javascript
{
"httpCode": 200,
"result": {
"data": {
"id": "a72ccbc3-947d-467e-914e-3928dad3270e",
"otp": "123456"
}
}
}
```
ErrorMsg:
```javascript
// 超過重送次數
{
"errorMsg": "SERVICE_ERROR.OTP_EXCEED_RESEND_TIMES",
"httpCode": 422
}
// OTP已過期
{
"errorMsg": "SERVICE_ERROR.OTP_EXPIRED",
"httpCode": 422
}
// OTP驗證失敗
{
"errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
"httpCode": 422
}
```
## 驗證OTP
* 不需token
Request:
```URL
POST /otp/validate
```
Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼
otp | String | Y | otp, 6位數字
```javascript
{
"countryCode": "+886",
"phone":"0987654321",
"otpType":"FORGOT_PW"
"otp": "123456"
}
```
Response:
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
```javascript
{
"httpCode": 200,
"result": {
"data": {
"id": "a72ccbc3-947d-467e-914e-3928dad3270e"
}
}
}
```
ErrorMsg:
```javascript
// OTP驗證失敗
{
"errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
"httpCode": 422
}
```
## 客服取OTP
* 不需token
* 客服取OTP的token會每日定時更換, 可以先詢問系統管理者
Request:
```URL
POST /otp/supervisor-call
```
Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼
supervisorToken | String | Y | 客服取OTP的專用token, 為6碼數字
```javascript
{
"countryCode": "+886",
"phone":"0987654321",
"otpType":"REGISTER",
"supervisorToken": "123456"
}
```
Response:
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
otp | String | otp, 6位數字, 測試用時顯示, 實際介接SMS發送時不會顯示此欄位
expireTime | Date | otp到期時間
```javascript
{
"httpCode": 200,
"result": {
"data": {
"id": "a72ccbc3-947d-467e-914e-3928dad3270e",
"otp": "123456",
"expiredTime": 1639992592000
}
}
}
```
ErrorMsg:
```javascript
// 使用的supervisorToken驗證失敗
{
"errorMsg": "SERVICE_ERROR.OTP_SUPERVISOR_FAIL",
"httpCode": 422
}
// 無此電話的OTP記錄
{
"errorMsg": "API_ERROR.NO_DATA",
"httpCode": 400
}
```
## 忘記密碼
* 不須有token
Request:
```URL
POST /generalPublic/forgotPassword
```
Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
password | String | Y | 密碼, 需加密
otpId | String | Y | otpId, 確保有成功驗證過otp
```javascript
{
"countryCode": "+886",
"phone":"0987654321",
"password": "LoM7aCNhoIHkcO+eoRUlKA==",
"otpId": "a72ccbc3-947d-467e-914e-3928dad3270e"
}
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": "true"
}
}
```
ErrorMsg:
```javascript
// 密碼重複未變更 PASSWORD_SAME_AS_OLD
{
"errorMsg": "SERVICE_ERROR.PASSWORD_SAME_AS_OLD",
"httpCode": 422
}
// 舊密碼錯誤
{
"errorMsg":"SERVICE_ERROR.PASSWORD_ERROR",
"httpCode": 422
}
// 帳號不存在
{
"errorMsg": "SERVICE_ERROR.ACCOUNT_NOT_EXISTS",
"httpCode": 422
}
// OTP驗證失敗
{
"errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
"httpCode": 422
}
```
## 取得App目前最新版本號
* 不須有token
Request:
```URL
GET /api/appLatestVersion
```
Response:
```javascript
{
"httpCode": 200,
"result": {
"data": {
"app_version_android": "2.0.8",
"app_version_ios": "2.0.8"
}
}
}
```
## 取得error code mappings
* 不須有token
Request:
```URL
GET /api/error-code-mappings
```
Response:
欄位 | 型態 | 說明
-|-|-
httpCode | int | http status code
errorCodes | errorCode json array | 錯誤碼json array
* errorCodes
欄位 | 型態 | 說明
-|-|-
httpCode | int | http status code
errorCode | string | errorCode, 對應到執行API後返回的error response json裡的"errorMsg"欄位
errorMessage | string | 對應到的錯誤訊息(預設語系)
langs | json array | 多語系json array
* langs
欄位 | 型態 | 說明
-|-|-
lang | string | 語系, 目前可用語系有 zh_TW(正體中文), en(英文)
message | string | 該語系訊息
```javascript
{
"httpCode": 200,
"result": {
"data": [
{
"httpCode": 400,
"errorCodes": [
{
"httpCode": 400,
"errorCode": "API_ERROR.USER_INFO_ERROR",
"errorMessage": "憑證資訊錯誤",
"langs": [
{
"lang": "zh_TW",
"message": "憑證資訊錯誤"
},
{
"lang": "en",
"message": "Certificate Error"
}
]
},
{
"httpCode": 400,
"errorCode": "API_ERROR.NOT_EXIST",
"errorMessage": "該資料不存在",
"langs": [
{
"lang": "zh_TW",
"message": "該資料不存在"
},
{
"lang": "en",
"message": "No Data"
}
]
},
...
]
},
{
"httpCode": 401,
"errorCodes": [
{
"httpCode": 401,
"errorCode": "API_ERROR.UNAUTHORIZED",
"errorMessage": "未經授權",
"langs": [
{
"lang": "zh_TW",
"message": "未經授權"
},
{
"lang": "en",
"message": "Unauthorized"
}
]
}
]
},
{
"httpCode": 403,
"errorCodes": [
{
"httpCode": 403,
"errorCode": "API_ERROR.PERMISSION_DENIED",
"errorMessage": "權限限制",
"langs": [
{
"lang": "zh_TW",
"message": "權限限制"
},
{
"lang": "en",
"message": "Permission Denied"
}
]
}
]
},
{
"httpCode": 422,
"errorCodes": [
{
"httpCode": 422,
"errorCode": "SERVICE_ERROR.MEMBER_NOT_EXIST",
"errorMessage": "成員不存在",
"langs": [
{
"lang": "zh_TW",
"message": "成員不存在"
},
{
"lang": "en",
"message": "Member does not exist."
}
]
},
...
]
}
]
}
}
```