> For the complete documentation index, see [llms.txt](https://gramhal.gitbook.io/matar/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gramhal.gitbook.io/matar/developer-reference/backend-code/user-registration.md).

# User Registration

{% hint style="info" %}
This page describes code related to user registration on Matar.
{% endhint %}

***

### User Login

The user login for Matar app provides [access\_token() ](https://flask-jwt-extended.readthedocs.io/en/3.0.0_release/api/#flask_jwt_extended.create_access_token)in form of JSON web tokens.

```python
def simple_login():
    ret_val = errors = {}
    phone_number = request.json.get("phone_number")
    action = request.json.get("action")
    source = request.json.get("source")
    organization_id = request.json.get("organization_id") or DEFAULT_ORGANIZATION_ID
    organization = Organization.query.get(organization_id)
    if(not organization):
        return {"error": "no such organization"}, 400

    if(action == "send_otp"):
        UniqueEntry.create_send_otp(
            phone_number=phone_number,
            errors=errors
        )
        if(not errors):
            return {"message": "sent otp"}, 200
        return errors, 400

    elif(action == "submit_otp"):
        name = request.json.get("name")
        image_url = request.json.get("image_url")
        otp = request.json.get("otp")
        fcm_token = request.json.get("fcm_token") or request.headers.environ.get("HTTP_FCM_TOKEN")
        print("fcm token user", request.json.get("fcm_token"))
        UniqueEntry.submit_otp(
            phone_number=phone_number,
            otp=otp,
            errors=errors
        )
        if(errors):
            return errors, 400

        user = User.query.filter(User.phone_number == phone_number).first()
        if(not user):
            user = User(
                phone_number=phone_number,
                name=name,
                image_url=image_url,
                source=source,
                roles={"default": [organization_id]},
                fcm_token=fcm_token
            )
            user.commit()
        elif(fcm_token):
            user.fcm_token = fcm_token
            user.commit()

        ret_val["access_token"] = create_access_token(identity=user._id, fresh=True)
        ret_val["refresh_token"] = create_refresh_token(user._id)

        return ret_val, 200
```

**Describing Code :**

* Starting the login flow ,user provides a phone numbers on which one-time verification otp (one-time password) is received via google firebase authentication.
* Then a specified user name ,received otp and a token from FCM (call Firebase. messaging. token ) has to be submitted. FCM token is received everytime\*\* the user opens the app \*\*to ensure the device has the right token, then update the timestamp and optionally the token if it has changed.
* Once all the details specified above are submitted an access and refresh token is generated via [create\_access\_token() ](https://flask-jwt-extended.readthedocs.io/en/stable/api.html#flask_jwt_extended.create_access_token)which is used to a make JSON web tokens. JSON Web Tokens(JWTs ) are a good way of securely transmitting information between client(app user) and server. JWTs are signed and uses public/private key pairs which ensure the senders are who they say they are.
* It calls a function (**UniqueEntry.submit\_otp**) to verify the OTP provided by the user. If there are errors, it returns an error response.It attempts to find a user with the specified **phone\_number**. If the user does not exist, it creates a new user record with the provided details, including **phone\_number**, **name**, **image\_url**, **source**, and **roles**.

***

### User Authentication

Here is a code snippet of how user authentication is protected with the functions below :

```javascript
def authentication_required(func):
    @jwt_required()
    def inner(*args, **kwargs):
        user_id = get_jwt_identity()
        user = User.query.get(user_id)
        if(not user):
            return {"error": "no such user"}, 403
        return func(user=user, *args, **kwargs)
    inner.__name__ = func.__name__
    return inner
```

**Describing Code :**

* When it comes to user authentication a JSON Web Token is used for authentication if valid you will be able to retrieve the authenticated user information using the  [get\_jwt\_identity()](https://flask-jwt-extended.readthedocs.io/en/3.0.0_release/api/#flask_jwt_extended.get_jwt_identity) function .The [jwt\_required()](https://flask-jwt-extended.readthedocs.io/en/3.0.0_release/api/#flask_jwt_extended.jwt_required) is used to protect all the routes or app paths when required authorization.
* The user object is fetched from a database using SQLAlchemy based on the user's identity (**user\_id**) obtained from the JWT token.
  1. If a user with the given identity is not found in the database, it returns a JSON response indicating an error with a 403 (Forbidden) status code.
  2. If a user is found in the database, it calls the original function (**func**) with the **user** object as an argument and passes any additional arguments and keyword arguments. This allows the original function to access the authenticated user.
  3. Finally, it sets the **\_\_name\_\_** attribute of the **inner** function to match the **func** function's name. This is done to preserve the name of the original function, which can be useful for debugging and introspection.
