Initial commit
This commit is contained in:
104
docs/zagros/2fa/2fa.md
Normal file
104
docs/zagros/2fa/2fa.md
Normal file
@@ -0,0 +1,104 @@
|
||||
#Registration: 2FA
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
2 factor authentication is a feature that helps users to secure their activities.
|
||||
For critical activities the app needs a code to be completed.
|
||||
At first vault creates a code (that showed with QR) to sync with google authenticator.
|
||||
After adding code in the user's google authenticator, every time a user needs OTP(one-time-password) can read it in his app.
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
GET {$domain}/api/v2/barong/resource/otp/generate_qrcode
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/enable
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/enable_2fa
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/disable
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/disable_email
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/otp.rb
|
||||
|
||||
#### Commits:
|
||||
bd7f980596
|
||||
dc95b308a6
|
||||
b3b5a08d60
|
||||
3c170120c1
|
||||
a79e06a71b
|
||||
8c821f1ba4
|
||||
e04a58b012
|
||||
99c2552404
|
||||
63f69ed0d6
|
||||
7010449976
|
||||
4d55a48572
|
||||
2da71b1097
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
We add an authorization step to enable/disable 2FA. After entering the google authenticator code, an authorization email is sent to the user containing an OTP . Users only can enable or disable 2FA after entering the correct OTP from the email.
|
||||
|
||||
New flow:
|
||||
|
||||
System generates the code → User scan it with mobile → enters the google code → Receives the email →The user enters the code → 2FA enable/disable
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: 2fa activation
|
||||
User->>Ranj: generate Qr Code
|
||||
Ranj-->>Dalan: get /generate_qrcode
|
||||
Dalan->>Ranj: 400, message: '2FA has been enabled for this account'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 400, message: '2FA has been already sent email for this account(enabling process started)'
|
||||
Dalan->>Ranj: 200, QR params
|
||||
Ranj->>User: QR
|
||||
User->>Ranj: User scan and enter code
|
||||
Ranj-->>Dalan: post /enable params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has been enabled for this account or code is missing'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 422, message: '2FA has been already sent email for this account(enabling process started)'
|
||||
Ranj->>User: show result
|
||||
Dalan->>User: send email in case of success
|
||||
User->>Ranj: enter authorization code
|
||||
Ranj-->>Dalan: post '/enable_2fa' params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has been enabled for this account or code is missing
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 400. message: '2FA has been already enabled for this account'
|
||||
Dalan->>Ranj: 400, message: '2FA hasnt been enable'(didnt start enabling process)
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 200
|
||||
Ranj->>User: success
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: 2fa deactivation
|
||||
User->>Ranj: enter google authentication code
|
||||
Ranj-->>Dalan: post /disable params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has not been enabled for this account or code is missing'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 422, message: '2FA has been already sent email for this account(disabling process started)'
|
||||
Ranj->>User: show result
|
||||
Dalan->>User: send email in case of success
|
||||
User->>Ranj: enter authorization code
|
||||
Ranj-->>Dalan: post '/disable_email' params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has not been enabled for this account or code is missing
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 400. message: '2FA has been already disabled for this account'
|
||||
Dalan->>Ranj: 400, message: '2FA has been already sent email for this account'(didnt start enabling process)
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 200
|
||||
Ranj->>User: success
|
||||
```
|
||||
|
||||
|
||||
BIN
docs/zagros/Dalan-document.pdf
Normal file
BIN
docs/zagros/Dalan-document.pdf
Normal file
Binary file not shown.
95
docs/zagros/KYC-steps/level-one/access-mobile.md
Normal file
95
docs/zagros/KYC-steps/level-one/access-mobile.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# KYC: Access mobile
|
||||
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
|
||||
User should enter his number, after the validation app sends a sms with an otp code, the user must enter the code to prove to us that he has access to the entered number.
|
||||
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/mobiles
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/mobiles/send_code
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/mobiles/verify
|
||||
|
||||
#### File destination:
|
||||
|
||||
{$Dalan_Path}/app/api/v2/resource/phones.rb
|
||||
|
||||
#### Commits:
|
||||
|
||||
bd7f980596
|
||||
695b0b56e2
|
||||
6dd40a9c42
|
||||
e04a58b012
|
||||
36167eda10
|
||||
2089690fe0
|
||||
90cbc48649
|
||||
17a5bce849
|
||||
63722fe22a
|
||||
63977c330d
|
||||
bff2746686
|
||||
75490dcb22
|
||||
f13ee3f4d5
|
||||
2c05522f77
|
||||
46c053b435
|
||||
551e7cdba2
|
||||
77d7b9a9b3
|
||||
2da71b1097
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
First of all we added a new service for our sms&call third party service(kavenegar).it needs its own initializer for private keys.in this service we also handle caching data(for storing keys and codes with expiration time) and creating OTP code by vault.
|
||||
|
||||
We created a new api for phones with our rules.
|
||||
after verification every number, app create a new label(access_phone) if there were not that label.
|
||||
note:
|
||||
|
||||
if user wants to enter new number:
|
||||
|
||||
1.if user has pending number --> legacy number will be update with new number
|
||||
|
||||
2.If user has verified access label --> new number must get access label to create in db and legacy one replaced
|
||||
|
||||
3.If user has verified ownership label --> new number must get both labels to create in db and legacy one replaced
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: access phone
|
||||
User->>Ranj: enter phone number with +98
|
||||
Ranj-->>Dalan: post /mobiles params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired'(there is an active process for addding new mobile)
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
note left of Dalan: if there is a pending number it will be replaced with new one
|
||||
Dalan->>KaveNegar: send sms to User in case of success
|
||||
KaveNegar->>User: SMS with code
|
||||
Ranj->>User: show result
|
||||
note right of User: if didnt catch sms
|
||||
|
||||
User->>Ranj: resend code
|
||||
Ranj->>Dalan: Post mobiles/send_code params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired' (expiration time doesnt finish)
|
||||
Dalan->>KaveNegar: send sms to User in case of success
|
||||
KaveNegar->>User: SMS with code
|
||||
Ranj->>User: show result
|
||||
User->>Ranj:enter code
|
||||
Ranj->>Dalan: Post mobiles/verify params
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 400, message: phone.verification_invalid
|
||||
note right of Ranj: if user wants to replace a new verified phone and the legacy phone has owner_phone label, we should check ownership. if it doesnt legacy phone labels all changes will be rollback.
|
||||
Dalan->>Ranj: success 2xx
|
||||
Ranj->>User: show result
|
||||
```
|
||||
45
docs/zagros/KYC-steps/level-one/bank-information.md
Normal file
45
docs/zagros/KYC-steps/level-one/bank-information.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# KYC: Bank information
|
||||
|
||||
### Outcome:
|
||||
we checking ownership of card-numbers and ibans.
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
Post {$domain}/api/v2/barong/resource/profiles/treasury
|
||||
|
||||
#### File destination:
|
||||
- {$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
- {$Dalan_Path}/app/workers/kyc/local/treasury_worker.rb
|
||||
- {$Dalan_Path}/app/services/jibit_service.rb
|
||||
|
||||
|
||||
#### Commits:
|
||||
- 40177a4f
|
||||
- 816fb00e
|
||||
- 9e17677b
|
||||
- 63977c33
|
||||
- c76f72fe
|
||||
- 90cbc486
|
||||
|
||||
#### What did we implement:
|
||||
We implemented a new model and table to keep users bank information and called it treasury.<br />
|
||||
After users entered their card_number or IBAN, we are sending this information to the Jibit service,<br />
|
||||
and then the Jibit Service returns the first name and last name of the real owner.<br />
|
||||
Now we can check this returned information to users' profile information to find out everything is ok.<br />
|
||||
It is worth mentioning that the steps of getting information from the Jibit and checking it with the profile are done in the background.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: bank information (treasury)
|
||||
note over User,Dalan: Users enter their bank information
|
||||
note over User,Dalan: `data` is card-number or iban value, `kind` is 'card' or 'iban'
|
||||
User->>Dalan:data, kind, title
|
||||
|
||||
note over Dalan,Jibit: Dalan send request to Jibbit service (as worker)
|
||||
Dalan->>Jibit:GET: iban value or card value (data)
|
||||
Jibit->>Dalan:Response: first-name and last-name of real owner
|
||||
Dalan->>Dalan: checking returned information with users profile data
|
||||
Dalan->>User: add a confirmed label if the names matched, otherwise rejected label was created.
|
||||
```
|
||||
38
docs/zagros/KYC-steps/level-one/personal-info.md
Normal file
38
docs/zagros/KYC-steps/level-one/personal-info.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# KYC: Personal info
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
Users add the below information to their profile
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST {$domain}/api/v2/barong/resource/profiles
|
||||
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
9f1cde76
|
||||
2422f5d1
|
||||
|
||||
#### What did we implement:
|
||||
In the Opendax, users can create their profiles by personal info and Address info in one step, also in this step there is no way to upload identity card
|
||||
|
||||
So In Zagros, we separate the step of adding personal info from adding address info step, and also we add upload identity card features
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: KYC - Profile Step
|
||||
note over User,Ranj:**upload** is a picture of front identity card
|
||||
User->>Ranj:first_name, last_name, dob, national_code, upload
|
||||
Ranj->>Dalan:Post: after client side checking
|
||||
Dalan->>Ranj:4xx if any required params are empty
|
||||
Dalan->>Ranj:4xx if Profile model validity fails
|
||||
Dalan->>Ranj:4xx if Document model validity fails
|
||||
Dalan->>Ranj:2xx the profile create successfully
|
||||
Ranj->>User:notify user that profile created
|
||||
```
|
||||
91
docs/zagros/KYC-steps/level-two/landline.md
Normal file
91
docs/zagros/KYC-steps/level-two/landline.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# KYC: landline
|
||||
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
|
||||
User should enter his number, after the validation app sends a call with an otp code, the user must enter the code to prove to us that he has access to the entered number.
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/phones
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/phones/send_code
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/phones/verify
|
||||
|
||||
#### File destination:
|
||||
|
||||
{$Dalan_Path}/app/api/v2/resource/phones.rb
|
||||
|
||||
#### Commits:
|
||||
|
||||
bd7f980596
|
||||
695b0b56e2
|
||||
6dd40a9c42
|
||||
e04a58b012
|
||||
36167eda10
|
||||
2089690fe0
|
||||
90cbc48649
|
||||
17a5bce849
|
||||
63722fe22a
|
||||
63977c330d
|
||||
bff2746686
|
||||
75490dcb22
|
||||
f13ee3f4d5
|
||||
2c05522f77
|
||||
46c053b435
|
||||
551e7cdba2
|
||||
77d7b9a9b3
|
||||
2da71b1097
|
||||
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
in access mobile told about KaveNegarService
|
||||
user entered landline number then system send call by kave negar with otp code
|
||||
user must enter send code to prove us that has access.
|
||||
|
||||
if user wants to enter new number:
|
||||
|
||||
1.if user have verified phone: response error
|
||||
|
||||
2.if user has pending number: update that number with new one
|
||||
|
||||
3.if user doesnt have number in our system: create new one
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: access landline
|
||||
User->>Ranj: enter landline number with +98
|
||||
Ranj-->>Dalan: post /phones params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired'(there is an active process for addding new landline) and phone.exists(has verified number in system)
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
note left of Dalan: if there is a pending number it will be replaced with new one
|
||||
Dalan->>KaveNegar: send call to User in case of success
|
||||
KaveNegar->>User: call with code
|
||||
Ranj->>User: show result
|
||||
note right of User: if didnt catch call
|
||||
|
||||
User->>Ranj: resend code
|
||||
Ranj->>Dalan: Post phones/send_code params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired' (expiration time doesnt finish)
|
||||
Dalan->>KaveNegar: send call to User in case of success
|
||||
KaveNegar->>User: call with code
|
||||
Ranj->>User: show result
|
||||
User->>Ranj:enter code
|
||||
Ranj->>Dalan: Post phones/verify params
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist', 'verification_invalid
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: success 2xx
|
||||
Ranj->>User: show result
|
||||
```
|
||||
42
docs/zagros/KYC-steps/level-two/mobile-ownership.md
Normal file
42
docs/zagros/KYC-steps/level-two/mobile-ownership.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# KYC: mobile ownership
|
||||
|
||||
### Outcome:
|
||||
we checking ownership of mobile.
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
PUT {$domain}/api/v2/barong/admin/profiles/label
|
||||
|
||||
#### File destination:
|
||||
- {$Dalan_Path}/app/workers/kyc/local/owner_mobile_worker.rb
|
||||
- {$Dalan_Path}/app/models/phone.rb
|
||||
- {$Dalan_Path}/app/services/kyc_service.rb
|
||||
- {$Dalan_Path}/app/api/v2/admin/profiles.rb
|
||||
- {$Dalan_Path}/app/services/jibit_service.rb
|
||||
|
||||
#### Commits:
|
||||
- 7f06a2e3
|
||||
- 816fb00e
|
||||
- 2c05522f
|
||||
- 90cbc486
|
||||
- 91e75604
|
||||
- bdfc578d
|
||||
|
||||
#### What did we implement:
|
||||
Ownership of mobile is done in background (worker) after last step (selfie confirmation).<br />
|
||||
The national code of verified profile with phone number , is sent to Jibit Service for matching.<br />
|
||||
The label key in the `labels` table is **owner_phone**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: mobile ownership
|
||||
note over Admin,Dalan: admin user confirm users selfie
|
||||
Admin->>PUT Dalan:user_uid, label_key, label_value
|
||||
|
||||
note over Dalan,Jibit: Dalan send request to Jibbit service (as worker)
|
||||
Dalan->>Jibit:GET: natonal_code, phone_number
|
||||
Jibit->>Dalan:Response: matched, false or true
|
||||
Dalan->>Dalan: create ownership label with reject label or verified label
|
||||
```
|
||||
72
docs/zagros/KYC-steps/level-two/residence.md
Normal file
72
docs/zagros/KYC-steps/level-two/residence.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# KYC: Residence
|
||||
|
||||
###### Sprint: ?
|
||||
|
||||
### Outcome:
|
||||
|
||||
User can add address with complete information(city and province and etc..)
|
||||
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/profiles/address
|
||||
|
||||
#### File destination:
|
||||
|
||||
{$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
|
||||
f7820d8
|
||||
3e0fff4
|
||||
67c41b3
|
||||
f420fa4
|
||||
bff2746
|
||||
63977c3
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
Opendax just implements address as a string but we need more information like city and province and document for residency.
|
||||
|
||||
So first of all we implemented city and province as below steps:
|
||||
|
||||
##### 1.create migrations:
|
||||
|
||||
20210420111532_create_provinces.rb → have just a name
|
||||
|
||||
20210420111629_create_cities.rb → have name and must connect to province(foreign key) references :province, foreign_key: true
|
||||
|
||||
|
||||
|
||||
##### 2.create models
|
||||
|
||||
Province model:
|
||||
|
||||
* Create validation for name: only allows letters, digits "-", "\'", and space. length: 1..255
|
||||
|
||||
* Mention to rails that this model has many cities
|
||||
|
||||
City model:
|
||||
* Mention to rails that this model belongs to province and this column is required.
|
||||
* Create validation for name: only allows letters, digits "-", "\'", and space. length: 1..255
|
||||
|
||||
we need seeds to fill city and province tables. So we used a JSON file from git and create a seed. data of the seed was put in config/seeds.yml file and the functions are in lib/barong/seed.rb.(seed_provinces and seed_cities) they check the existence of the data(city or province) then create it in db.
|
||||
|
||||
After these steps, we were ready to create a new API. we check the existence of the city and province that the user has been sent and create poa label. if user submitted another doc for poa and it has not been accepted, the new document will be replaced.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: residence
|
||||
User->>Ranj: residence information
|
||||
Ranj-->>Dalan: post /profiles/address params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'needed data doesnt exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors',(address.already_exist,province_doesnt_exist)
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired'(there is an active process for addding new mobile)
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
note left of Dalan: if there is a pending address it will be replaced with new one
|
||||
```
|
||||
|
||||
|
||||
|
||||
38
docs/zagros/KYC-steps/level-two/selfie.md
Normal file
38
docs/zagros/KYC-steps/level-two/selfie.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# KYC: Selfie
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
Users can upload image for certification (the image includes selfie and signed text of the agreement )
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST{$domain}/api/v2/barong/resource/profiles/selfie
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
ac083d21
|
||||
ea79c211
|
||||
|
||||
#### What did we implement:
|
||||
Users can upload images for the Selfie KYC step. In the first place that image is in a `pending` state.
|
||||
In the Admin panel, this image must be change state from `pending` to `confirm` or `reject`
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: KYC - Selfie
|
||||
|
||||
note over User,Ranj: **upload** must be valid format of image (jpg, jpeg, png)
|
||||
User->>Ranj: upload
|
||||
Ranj->>Dalan:Post: after client side checking
|
||||
Dalan->>Ranj:4xx if does not exist verified profile for the current user
|
||||
Dalan->>Ranj:4xx if before exist verified selfie image for the current user
|
||||
Dalan->>Ranj:2xx update (if exist unconfirmed ) or create new selfie
|
||||
Ranj->>User:notify user that password changed
|
||||
```
|
||||
78
docs/zagros/KYC-steps/leveling.md
Normal file
78
docs/zagros/KYC-steps/leveling.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# KYC level logic
|
||||
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
Users can upgrade their level by doing KYC processes
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/models/user.rb<br />
|
||||
{$Dalan_Path}/app/models/document.rb<br />
|
||||
{$Dalan_Path}/app/models/label.rb<br />
|
||||
{$Dalan_Path}/app/models/level.rb<br />
|
||||
{$Dalan_Path}/app/models/treasury.rb<br />
|
||||
{$Dalan_Path}/app/models/profile.rb<br />
|
||||
{$Dalan_Path}/app/services/kyc_service.rb
|
||||
|
||||
|
||||
#### Commits:
|
||||
2422f5d1
|
||||
40177a4f
|
||||
ac083d21
|
||||
7f06a2e3
|
||||
816fb00e
|
||||
2c05522f
|
||||
9e17677b
|
||||
bff27466
|
||||
63977c33
|
||||
c76f72fe
|
||||
90cbc486
|
||||
6dd40a9c
|
||||
695b0b56
|
||||
b3b5a08d
|
||||
bd7f9805
|
||||
|
||||
#### What did we implement:
|
||||
in the Opendax, KYC level handled by labels that id of them (label) shows user level,
|
||||
but not support feature that per-user level has own steps
|
||||
(each label is database record as Label model)
|
||||
obviously per step has its own label too and the label has a unique id itself.
|
||||
|
||||
so by considering this rule in the Opendax, we kept it but change some things to support multi-steps.<br />
|
||||
we implement some kind of giving-points system.
|
||||
users can achieve a new level If the sum of their label IDs reaches a certain limit that defines in the code.
|
||||
|
||||
as you know, each step is a kind of record database that controlling by model so:<br />
|
||||
bank information step is `Treasury` model
|
||||
selfie and address step is `Document` model (for uploading)
|
||||
mobile and landline steps are `Telephone` model
|
||||
profile is `Profile` model
|
||||
|
||||
so if one of the above kind records, is updated or created, we will create or update the corresponding label recording,
|
||||
and if the label is created or updated we will change the users level by calculating their points (points are the sum of label ids)
|
||||
|
||||
also, we keep levels (steps for KYC) in the Level model with the below data that was entered by seed
|
||||
|
||||
|
||||
levels:
|
||||
- key: email, id: 1 ,value: verified, description: "User enter a valid code after registration"
|
||||
- key: profile, id: 2, value: verified, description: "User personal documents have been verified"
|
||||
- key: access_phone, id: 3, value: verified, description: "User entered a valid code from sms"
|
||||
- key: card, id: 4, value: verified, description: "User card number have been verified"
|
||||
- key: iban, id: 5, value: verified, description: "User iban have been verified"
|
||||
- key: poa id: 6, value: verified, description: "User card bank have been verified"
|
||||
- key: telephone id: 7, value: verified, description: "User entered a valid code from ring call"
|
||||
- key: selfie id: 8, value: verified, description: "User selfie documents have been verified"
|
||||
- key: owner_phone id: 9, value: verified description: "User owner mobile have been verified"
|
||||
- key: vip id: 10, value: verified, description: "User Vip have been verified"
|
||||
|
||||
### TODO
|
||||
now if the label being confirmed accidental in the admin panel, they can not delete it,<br />
|
||||
so must implement new codes to handle this stuff
|
||||
|
||||
|
||||
|
||||
38
docs/zagros/admin/KYC-confirm.md
Normal file
38
docs/zagros/admin/KYC-confirm.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# KYC: admin
|
||||
###### Sprint: ?
|
||||
|
||||
### Outcome:
|
||||
admin can verify or reject(change state(selfie,poa)) of documents.
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/admin/users/documents
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/admin/users.rb
|
||||
|
||||
#### Commits:
|
||||
bd7f980
|
||||
|
||||
#### What did we implement:
|
||||
for admin apis, we should check access of user(authorization) at first.
|
||||
after checking authorization, we checked existence of document and profile for related user.
|
||||
update state of document.
|
||||
we wrote some callbacks for every doc type to update labels state .
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: admin document update
|
||||
User->>Ranj: user and new state of doc
|
||||
Ranj-->>Dalan: post /admin/users/documents params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token', 'admin.ability.not_permitted'
|
||||
Dalan->>Ranj: 404, message: 'doesnt exist'(document.user_doesnt_exist,document.document_doesnt_exist)
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
Ranj->>User: show admin result
|
||||
```
|
||||
28
docs/zagros/admin/treasury-list.md
Normal file
28
docs/zagros/admin/treasury-list.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Admin API: list treasuries
|
||||
|
||||
### Outcome:
|
||||
list (Array) of users treasuries
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
GET {$domain}/api/v2/barong/admin/profiles/treasury/list
|
||||
|
||||
#### File destination:
|
||||
- {$Dalan_Path}/app/api/v2/admin/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
- 0654aa1a04
|
||||
|
||||
#### What did we implement:
|
||||
We implemented one API in the panel that admin users can see a list of users' treasuries by entering user_id.<br />
|
||||
also, admin users can filter responses as IBAN or card treasuries by sending kind value.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: list treasuries
|
||||
note over Admin,Dalan: **kind** is optional
|
||||
Admin->>Dalan:GET user_uid, kind
|
||||
Dalan->>Admin:Array of treasuries [id, title, state, data, created_at, updated_at]
|
||||
```
|
||||
63
docs/zagros/change-password/change-password.md
Normal file
63
docs/zagros/change-password/change-password.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Registration: Change password
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
Users can change login password by entering old and new password and confirm OTP code
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
PUT {$domain}/api/v2/barong/resource/users/password
|
||||
|
||||
POST {$domain}/api/v2/barong/identity/confirm_password
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/users.rb
|
||||
|
||||
#### Commits:
|
||||
fb5162e5
|
||||
8b16cc49
|
||||
fb9db4ee
|
||||
70104499
|
||||
63f69ed0
|
||||
0ee97595
|
||||
9e17677b
|
||||
5bb29d79
|
||||
|
||||
#### What did we implement:
|
||||
In the Opendax, users can change their current password without confirming the OTP code that must be sent to its mail. Also, there is not any limitation for attempting to enter the current password.
|
||||
|
||||
In Zagros, if users enter the wrong current password more than 3 times, they are kicked out from the logged state and the new password is just accepted after entering the valid OTP code.
|
||||
|
||||
```
|
||||
TODO:
|
||||
Number of failed attempts to enter the current password must be dynamic and
|
||||
changeable by the admin panel
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: Change password
|
||||
|
||||
note over User,Ranj: old password parameter is the same as current password
|
||||
User->>Ranj:old_password, new_password, confirm_password
|
||||
Ranj->>Dalan:Put: after client side checking
|
||||
Dalan->>Ranj:4xx if attempt number for entering the valid current password is over
|
||||
Dalan->>Ranj:4xx if new_password is not same to confirm_password
|
||||
Dalan->>Ranj:4xx if old_password is not valid
|
||||
Dalan->>Ranj:4xx if new_password is same to old_password
|
||||
Dalan->>Ranj:4xx if length of new password is not valid
|
||||
Dalan->>User:2xx send otp to his or her mail
|
||||
Ranj->>User:Ask OTP code for confirming
|
||||
User-->>Ranj:if OTP code not received, try for resend after <color:#red>120</color> seconds
|
||||
Ranj-->>Dalan: Ask for sending OTP code again
|
||||
Dalan-->>User:2xx send otp to his or her mail
|
||||
User->>Ranj: enter OTP code
|
||||
Dalan->>Ranj:4xx if user does not exist in the system
|
||||
Ranj->>Dalan:Post : OTP code for checking ice
|
||||
Dalan->>Ranj:4xx if OTP code expired
|
||||
Dalan->>Ranj:2xx change user password
|
||||
Ranj->>User:notify user that password changed
|
||||
```
|
||||
53
docs/zagros/reset-password/reset-password.md
Normal file
53
docs/zagros/reset-password/reset-password.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Registration: Reset password
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
Users can reset login password by entering email and confirm by OTP code
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST {$domain}/api/v2/barong/identity/users/password/generate_code
|
||||
POST {$domain}/api/v2/barong/identity/users/password/confirm_code
|
||||
POST {$domain}/api/v2/barong/identity/users/password/reset
|
||||
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/identity/users.rb
|
||||
|
||||
#### Commits:
|
||||
9e17677b
|
||||
42b34ae2
|
||||
e04a58b0
|
||||
|
||||
#### What did we implement:
|
||||
In the Opendax, users get a reset token by entering their email, after in reset password page user can reset the password by entering a valid reset token and a new password
|
||||
|
||||
In Zagros, the reset password process is done in 3 steps, the first step is to generate OTP code by Vault, then is a step to check the OTP code in by separate API, and then reset the password
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: Reset password
|
||||
|
||||
User->>Ranj:email
|
||||
Ranj->>Dalan:Post: after client side checking
|
||||
Dalan->>Ranj:4xx if the user does not exist
|
||||
Dalan->>User:2xx send otp to his or her mail
|
||||
Ranj->>User:Ask OTP code for confirming
|
||||
User-->>Ranj:if OTP code not received, try for resend after <color:#red>120</color> seconds
|
||||
Ranj-->>Dalan: Ask for sending OTP code again
|
||||
Dalan-->>User:2xx send otp to his or her mail
|
||||
User->>Ranj: enter OTP code
|
||||
Ranj->>Dalan: OTP code for checking
|
||||
Dalan->>Ranj:4xx if user does not exist in the system
|
||||
Dalan->>Ranj:4xx if OTP code expired
|
||||
Dalan->>Ranj:2xx OTP code is check\n
|
||||
Ranj->>User: show reset password page
|
||||
Ranj->>Dalan: email, password, confirm_password
|
||||
Dalan->>Ranj:4xx if user does not exist in the system
|
||||
Dalan->>Ranj:4xx if new_password is not same to confirm_password
|
||||
Dalan->>Ranj:4xx if new password is not strong
|
||||
Dalan->>Ranj:2xx reset user password
|
||||
Ranj->>User:notify user that password changed
|
||||
```
|
||||
56
docs/zagros/sign-up/sign-up.md
Normal file
56
docs/zagros/sign-up/sign-up.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Registration: Sign-up
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
Users can register via an email and a strong password, then we send OTP code to this email, the user must confirm the email by entering the OTP code.
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST: {$domain}/api/v2/barong/identity/users
|
||||
|
||||
POST: {$domain}/api/v2/barong/identity/confirm_email
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/identity/users.rb
|
||||
|
||||
#### Commits:
|
||||
42602037
|
||||
Fb5162e5
|
||||
f57aaf35
|
||||
fb9db4ee
|
||||
70104499
|
||||
63f69ed0
|
||||
99c25524
|
||||
0ee97595
|
||||
|
||||
#### What did we implement?
|
||||
In the Opendax, users confirm their email by a unique link that is sent to their email, also in the registration process if one person uses an incorrect email, the email locks forever so the real owner of the email can not register ever.
|
||||
In the Zagros, the email will lock when confirming it and this confirming happens when the user enters the Six digits OTP code in the website.
|
||||
To send OTP code, we use Vault Service and adding action variable to distinguish every use of the Vault (for example to use it in following processes: Sign up, Change password, reset password and etc) also, email duplication in the registration process is allowed until the email confirmation or ban email in the system
|
||||
|
||||
`Ps: action is a new variable that passes to ruby vault service.`
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: Sign up
|
||||
|
||||
note over User,Ranj:starred parameters are optional
|
||||
User->>Ranj:email, password, *refid*
|
||||
Ranj->>Dalan:Post : after client side checking
|
||||
Dalan->>Ranj:4xx if user status is active or ban
|
||||
Dalan->>Ranj:4xx if email or password not valid
|
||||
Dalan->>User:2xx send otp to his or her mail
|
||||
Ranj->>User:Ask OTP code for confirming
|
||||
User-->>Ranj:if OTP code not received, try for resend after 120 seconds
|
||||
Ranj-->>Dalan:Ask for sending OTP code again
|
||||
Dalan-->>User:2xx send otp to his or her mail
|
||||
User->>Ranj: enter OTP code
|
||||
Ranj->>Dalan:Post : OTP code for checking
|
||||
Dalan->>Ranj:4xx if OTP code expired
|
||||
Dalan->>Ranj:4xx if user not exist in system
|
||||
Dalan->>Ranj:2xx create user, return user information
|
||||
Ranj->>User:Redirect user to the main page
|
||||
```
|
||||
31
docs/zagros/uploader/uploader.md
Normal file
31
docs/zagros/uploader/uploader.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Uploader
|
||||
|
||||
The uploader **principle** defines that who is responsible for saving any document type in the system and how does it.
|
||||
|
||||
the Opendax support these providers as uploader type
|
||||
`local` `google` `aws` `alicloud`
|
||||
|
||||
for `google`, `aws`, and `local` type, the UploadUploader class is a provider,
|
||||
this class is a child from this gem :
|
||||
[carrierwave](https://github.com/carrierwaveuploader/carrierwave)
|
||||
|
||||
**path of file** : app/uploaders/upload_uploader.rb
|
||||
|
||||
but for `alicloud` type, the provider is `AliUploader` class
|
||||
|
||||
**path of file** : app/uploaders/ali_uploader.rb that this class in the child of carrierwave gem too.
|
||||
|
||||
|
||||
in the `Dalan` version, we save files without any encryption
|
||||
and use only `local` type for uploader and this config exist in alvand/config/app.yml
|
||||
|
||||
the path of uploaded file is :
|
||||
|
||||
```"public/uploads/#{model.class.to_s.underscore}/upload/#{model.id}"
|
||||
example : public/uploads/document/upload/1/front_card.png
|
||||
```
|
||||
###TODO
|
||||
#### [Fog](https://fog.io/storage/)
|
||||
in app/uploaders/upload_uploader.rb , we change the config code to hardcode to always use `local` type,
|
||||
if you want to use fog type you must revert these lines:
|
||||
line 4 to 12
|
||||
Reference in New Issue
Block a user