# Introduction

The entire app is built with Flask for the backend, using Python and basic HTML templates for the frontend.

For questions, bug reports, or feature requests, please open a new GitHub issue in the main repository. If you need direct or specialized support, feel free to reach out at **<techsupport@icbest.ca>**

### Important Links:

[Main GitHub Repository](https://github.com/icbestCA/giftmanager)

[Docker Image](https://hub.docker.com/r/icbest/giftmanager)


# Features

**Sleek and Adaptable Design**: Powered by Tailwind CSS, providing a responsive layout that looks great on any device.

**Effortless Interaction**: Intuitive SVG icons enhance every button, making navigation seamless.

**Comprehensive Control**: Seamlessly add, edit, and delete gift ideas.

**Secret santa**: Ramdomly assigned between selected users with great interface for easy understanding.

**Detailed Information**: Include important details for each gift idea, such as name, description, and link.

**Automated Alerts**: Effortlessly mark ideas as "Bought" or "Not Bought," with [*email alerts automatically*](#user-content-fn-1)[^1] sent to buyers when ideas are removed.

**Complete Transparency**: View all relevant information for your gift ideas, including who added them and who bought them.

**Organized and Personalized**: Keep your gift lists tidy, with each user's list displayed alphabetically and your own list always at the top.

**Surprise Preservation**: Keep the excitement alive—others can see if an idea is bought, but you cannot, so you won’t know what gifts you’ll receive. Additionally, you won’t see what others have added to your list, keeping surprises intact.

**Easy Management and Installation for the Admin**: Simplify administrative tasks with an intuitive interface and straightforward installation process, ensuring smooth operation and quick setup.

[^1]: Require free Mailjet plan. This function is optional.


# Installation

### Docker Compose

You can use the docker image on the docker hub. It is using the same latest code as the folder "Docker" on the Github repo.

[icbest/giftmanager](https://hub.docker.com/r/icbest/giftmanager)

To use Docker Compose, copy, on your machine, the file [docker-compose.yml](https://github.com/icbestCA/giftmanager/blob/main/docker-compose.yml) from the repo.

You will need to edit the volume path to keep your data files in the correct folder.

```
volumes:
      - C:/Users/user1/documents/data:/app/data/
```

Modify only this part `C:/Users/user1/documents/data` to mount the folder on your machine.

When updating, keep the files where they are and just create a new container but mount it to the same folder on the host machine.

Edit the port you want to expose on the web.

```
ports:
      - "[port]:5000"
```

To run the container enter the directory of your docker-compose.yml file then in the terminal execute the following command:&#x20;

```
docker compose up -d && docker compose logs -f
```

You should see the image being pulled and the flask app being started.

Now head to [setup](/giftmanager-docs/getting-started/setup) and follow the steps to configure the app.

### Docker Run

You can use the docker image on the docker hub. It is using the same latest code as the folder "Docker" on the Github repo.

[icbest/giftmanager](https://hub.docker.com/r/icbest/giftmanager)&#x20;

Run the following command to run the container:

```
docker run -p [published-port]:5000 -d -v /path/to/data:/app/data icbest/giftmanager 
```

Change the port on which you want to access, making the command like that:  80:5000  you could now access on port 80 in browser.

**Make sure** to add a path so the app can store the data on the host machine like that:&#x20;

Linux: `/root/data:/app/data`

Windows: `C:/Users/user1/documents/data:/app/data`

When updating, keep the files where they are and just create a new container but mount it to the same folder on the host machine.

Now head to [setup](/giftmanager-docs/getting-started/setup) and follow the steps to configure the app.

### Python Gunicorn (Linux Only)

**Make sure you have latest Python installed and Pip.**

1. Download the app folder in the [main repository](https://github.com/icbestCA/giftmanager).
2. Make sure to put the folder is unzipped and in a directory that make sense to you.
3. Inside the main directory, install requirements.txt with the following command:

```
pip install -r requirements.txt
```

4. Still inside the `app.py` directory run the command bellow to make sure everything is working and see the errors messages if any. You can access on port 5000

```
flask run --host=0.0.0.0
```

5. If everything run fine, you can deploy in production with [Gunicorn](https://gunicorn.org/).

```
gunicorn app:app -w 1 --threads 4 -b 0.0.0.0:80 
```

Here the command `-w 1` : The number of workers, i recommend on 1 because using a json database it does some glitch with multiple workers. For faster loading time we use 4 threads which remains on one workers to prevent glitches. `-b 0.0.0.0:80`: The publish port, use port 80 so you can access it on default http. `app:app`: Define the file for the app.py .

6. Go to [setup ](/giftmanager-docs/getting-started/setup)and follow the steps


# Setup

Steps:

* Login with one of the default user, demo/password or user2/password2
* Create your own account.
* Delete the default accounts:
  * Log in with your own account.
  * Go to /delete\_default\_profiles.
  * Enter the password for the current logged username.
  * Hit delete and restart the app.
* Verify that user2 and demo have been removed from the list.
* You are now an admin. The admin is identified by the following line in the `users.json` file: `"admin": true`
* Head to /setup to edit the environment variables in the .env file.
  * FEED\_SEND: email address you wish to receive the feedback form answers
  * MAILJET...: enter your Mailjet API credentials to be able to send emails notifications. You MUST create a mailjet account to make the feature work. *The feature is optional, leave the API fields blank to disable it.*
  * SYSTEM\_EMAIL: The email you added to mailjet. All notifications will be send with this one.
  * DELETE\_DAYS: See [*Delete Script*](/giftmanager-docs/pages-and-functions/delete-script)


# Backups

If you want to backup your data, you just need to copy the `users.json` and `ideas.json` these are the only files containing the data. Go to /setup to download or restore those two files.

### Docker Backups

Backup the two files stored in the data folder mounted with the container.

### Restore

If previous files exist they will be loaded in priority if located in the right same folder as mounted.


# Basic to know

Each idea have a unique ID so when you edit ideas or mark as bought we use this ID to change the state. For handling users actions we use their username for login. But for displaying we use the full name which we retrieve using a function.


# Login

**Logic**:

* Retrieve the username and password from the template.
* Hash the password using `Argon2id` with the module argon2 on default parameters
* Compare the hashed password and username (NOT case-sensitive) against entries in `users.json`.
* Set the session cookie upon successful authentication.

**Frontend**:

* The `login.html` template show a banner with the instruction to contact an already registered family member if no account. Will show errors messages if <mark style="color:red;">User does not exist</mark> or <mark style="color:red;">Wrong password</mark>.


# OIDC Support

OpenID connect allow you to connect to the app using a third-party auth provider like [Authelia](https://www.authelia.com/), [Authentik](https://goauthentik.io/), [keycloak ](https://www.keycloak.org/)and more. With OIDC, users only need to authenticate with the provider once to access all configured applications without additional passwords.

### Configuration

**After any changes you need to restart the app to apply them.** After entering the `client ID` the button for OIDC connection will appear on the login page. This uses the /login\_oidc route then call /auth for the verification.

#### Connection Setup

To configure OIDC, add the following values to the `.env` file, either using the `/setup` route or by manually editing the file with a command like `docker exec`:

```
OIDC_CLIENT_ID=' '
OIDC_CLIENT_SECRET=' '
OIDC_SERVER_METADATA_URL=' '
OIDC_LOGOUT_URL=' '
```

You can find all those values quite easily in the provider's dashboard but here some hints: Server metadata URL usually end with this `/.well-known/openid-configuration` Logout URL usually end with this `/logout`

#### Scopes, Claims, and Database Field Mapping

The next parameters are used to compare the received values from the OIDC with the JSON users database.

```
PRIMARY_OIDC_FIELD='email'
SECONDARY_OIDC_FIELD='preferred_username'
PRIMARY_DB_FIELD='email'
SECONDARY_DB_FIELD='username'
```

These defaults are recommended but can be customized. Here are some common OIDC fields:

**OIDC**

You will need to confirm with the provider system but those are the most common used:

* given\_name (the full name)
* email (used to register in the provider)
* preferred\_username (username for login in the provider)

**JSON**

You can compare the previous values with the ones present in the JSON but under a different name.

* full\_name
* email
* username

The app will check for matching values in these fields and log in the user if there is a match.

#### Recommendations

Using the default field mappings is recommended, as they are widely supported. This setup compares values from the OIDC provider and the app's database to ensure that at least **one field** matches, allowing user login.

#### Auto Registration

If a user attempts to log in via OIDC and no matching fields are found, they can create a profile in the app. This will redirect them to `/setup_profile`, where they can provide any additional information not supplied by the OIDC provider, such as their birthday, avatar, and full name. Auto-registration is disabled by default but can be enabled by setting `ENABLE_AUTO_REGISTRATION=true` in the `.env` file.

#### Disable Login Form

To enforce OIDC for users, set the environment variable `ENABLE_DEFAULT_LOGIN` to `false`, allowing only the OIDC button to be displayed.


# Dashboard

**Logic**:

* Load the `dashboard.html` template.
* List users in alphabetical order with the current user at the top.
* Display the current user's full name and birthdate in the sidebar.

**Frontend**:

* Top: Four buttons (sidebar toggle, see bought items, help page, [secret santa,](#user-content-fn-1)[^1] add new ideas).
* Center: User list in the order determined by the backend.
* Sidebar (toggleable): Access account parameters, change password and email address, add users, and log out.

[^1]: If user is selected and in a pool


# User Gift Ideas

**Logic**:

* If the current user is accessing their own list, redirect to `my_ideas` to prevent them from seeing which gifts others have bought or added for them.

**Frontend**:

* Each idea is in its own container with the following elements:
  * Title
  * Description
  * Estimated value in $ entered by the user
  * Added by (user who added the idea)
  * Button to mark as bought/not bought (with the buyer's name)
  * Delete and edit buttons (if the current user added the idea)
  * Link button (if provided)
* If no ideas are available, redirect to the `noidea` page.


# My Ideas

* Only the connected user can see this page
* Shows only the ideas added by the current user to keep the surprise of the ideas added the others. The status is also not shown (bought or not).
* The user can edit the priority of the ideas, using the `reorder` button and the drag-n-drop feature to change the priority number. They will be at top on the User Gift Ideas page.


# Edit Ideas

**Logic**:

* Verify if the current user is editing their own list or an idea they added.
* Replace the description and link with the new input values.
* Title editing is disabled to prevent complete changes to ideas.

**Frontend**:

* Three fields (pre-populated with current values): description, link and value.
* Save changes button.


# Add Ideas

**Logic**:

* Basic route (`add_ideas`):
  * Preselect the user in the drop-down list if accessed from a user list.
  * Extract full names from the JSON and pass them to the HTML template, was built around the usernmae, so need to convert to full names.
  * Title is required; description and external link are optional.
* Secondary route (`add2`):
  * No preselection in the drop-down list as the button is on the main dashboard.

**Frontend**:

* User selection drop-down list.
* Title field (required).
* Description, value and external link fields (optional).
* Add button.


# Add User

**Logic**:

* Extract required fields (username, password, full name, birthday) from the POST request.
* Extract optional fields (email, avatar) using `request.form.get`.
* Hash the plain text password into an SHA-1 string and save it in the JSON.
* Write the new data to the JSON file.

**Frontend**:

* Four mandatory fields: username (for login), password, full name, birthday (not currently used).
* Optional email field (used for email notifications).
* Avatar selection: choose from six avatars, replace files in `static/icons` with appropriately named PNG files (`avatar1.png`, `avatar2.png`, etc.) if you want different ones.


# Families Management

### Creating and Managing Groups

#### Add a New Group

To create a new group:

1. Use the **form** to enter the **group name**.
2. **Select at least one user** to be added to the group (a group cannot be created without users).
3. Click **Save** to create the group.

> **Note:** If a group is created without any users, it will be automatically deleted.

#### Selecting Users for Groups

* Use the **checkbox** next to each user's name to add them to a group.
* Users can be in **multiple groups**.

### Important Considerations

* **Users without a group** are visible to everyone and can see everyone.
* Only **admins** can access the group management page.
* Users in different groups can be accessed via a **direct URL**, but they **cannot be viewed through the app interface**.
* Always **save changes** after updating the permissions grid to ensure proper configuration.


# Secret Santa

1. **Navigate to** `/secret_santa` (admin access required).
2. **Select Participants**: Choose the participants which will be randomly picked to give a gift to another participant.
3. **Add Pool Name**: Create multiple Secret Santa pools for different groups or families. Users can be part of multiple pools simultaneously. So give it a unique name like your family name.
4. **Add Instructions**: Include details such as average price, guidelines, and any other essential notes for participants.
5. **User Revelation**: Participants will see a new icon on their dashboard. Clicking this icon takes them to their assignment page (`/secret_santa_assignment`), where they’ll find out who they’re buying a gift for and the organizer’s instructions.
6. **Ending**: To conclude a Secret Santa event, go back to `/secret_santa`, enter the pool name, and click **Delete Pool** to remove it.

**Backend:**

* Each participant's assignment is stored in `users.json` in this format:

```json
"assigned_users": {
            "pool1": "username2",
            "pool2": "username3"
}
```

* Instructions are saved in a new text file `santa_inst_<poolname>.txt` for easy reference.

<figure><img src="https://2189090169-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZL6PAZpP3o7bKuehy0u9%2Fuploads%2FqkuHIKgox75V1oyMpLNQ%2Fsecret-santa.svg?alt=media&amp;token=67c0e6d0-99a2-4459-8258-97b50427016a" alt=""><figcaption><p>This icon</p></figcaption></figure>


# Delete Script

#### Bulk Removal of Bought Ideas

* To **permanently remove** ideas that have been marked as bought for a specific period of time **without sending email alerts**, go to `/rundl`.
  * This will trigger the `delete.py` script.
  * The script will delete ideas that have been marked as bought for the set number of days, and **no email notifications will be sent**.
  * You’ll see the script’s output, showing how many ideas were deleted.
  * **Restart the app** to apply the changes.
* To set the time period after which bought ideas should be removed, go to `/setup` and edit the value called `DELETE_DAYS` in the `.env` file.
* You will see the last execution in the file called `last_execution_time.txt`


# Help / FAQ  page

**Logic**:

* Retrieve name, email, and feedback from the POST request.
* Construct and send an email using Mailjet with the provided information.
* Display a success message if the email is sent successfully; otherwise, display an error message.
* Redirect to the feedback form page after submission.

**Frontend**:

* Form fields:
  * Name (required)
  * Email (optional)
  * Feedback (required)
* Submit button to send the feedback.
* Two informational sections:
  * FAQ: Clickable questions reveal or hide answers.
  * Tutorials: Clickable titles reveal or hide content.


# Introduction

The entire app is built with Flask for the backend, using Python and basic HTML templates for the frontend.

For questions, bug reports, or feature requests, please open a new GitHub issue in the main repository. If you need direct or specialized support, feel free to reach out at **<techsupport@icbest.ca>**

**Demo Here:** [**https://giftmanagerdemo.pages.dev/**](https://giftmanagerdemo.pages.dev/)

### Important Links:

[Main GitHub Repository](https://github.com/icbestCA/giftmanager)

[Docker Image](https://hub.docker.com/r/icbest/giftmanager)

### Screenshots

<div><figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2FVGjB12zMK2JgMMvgP6VB%2Ffirefox_b0H0gE2DrY.png?alt=media&amp;token=5a5de00e-4e3a-4112-a15c-29784404e3ee" alt=""><figcaption></figcaption></figure> <figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2Fi7fseakrGQ2EQOPVz8a2%2Ffirefox_ptKiDfrz6J.png?alt=media&amp;token=ba3d71f1-0f35-40ae-b02c-f2150e7b5af2" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2FVuC8hz7gepy1wuVQaVwr%2Ffirefox_H5fG4nF7uL.png?alt=media&amp;token=88658008-f2df-4add-b853-cdbb9fd9e17c" alt=""><figcaption></figcaption></figure> <figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2FLKPzDlDvjIEgbHpqMlyj%2Ffirefox_JiKT8FWU86.png?alt=media&amp;token=d6876bc9-5a45-4856-9926-a7ae2daac681" alt=""><figcaption></figcaption></figure> <figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2FNL3ivR7CGpOxD67PtwlR%2Ffirefox_QH6LjO2Nvs.png?alt=media&amp;token=0a9edb40-25c9-4ad9-8823-5bf2baf34412" alt=""><figcaption></figcaption></figure> <figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2F8C83JHnGBWw1V00YpLfn%2Ffirefox_U5WWHHElTf.png?alt=media&amp;token=08fdeecc-d7b9-4535-993a-685298d2fc28" alt=""><figcaption></figcaption></figure></div>


# Features

#### Gift Ideas Management

* Add and edit gift ideas for yourself and others.
* Organize with **descriptions, links,** and prices.
* Sort ideas however you like.
* Mark gifts as bought to **avoid duplicates.**
* Keep track of everything you’ve given.
* Built to keep **surprises secret**!

#### Nice Features

* Secret Santa made simple.
* Emails notifications.
* Dark mode included.
* Manage multiple families separately.

#### Global Management

* Easy-to-use **admin dashboard**.
* Built-in user management.
* Secure login with OIDC.


# Installation

### Tags and Versions

{% hint style="success" %}
Images available in amd64 and arm64 under the same tag name. (v2.6.0 and upward)
{% endhint %}

Docker images use the following tagging conventions:

* **Version-specific tags (English):** `:v2.4.1`
* **Version-specific tags (other languages):** `:v2.4.1-fr`

  > Refer to the table below to find the earliest available version in your language.
* **Latest version (English):** `:latest`
* **Latest version (other languages):** `:latest-fr`

  > Use these tags to always pull the most up-to-date image in the desired language, if available.

| Language | Code    | Earliest Available Version |
| -------- | ------- | -------------------------- |
| English  | DEFAULT | ALL VERSIONS               |
| French   | fr      | v2.4.1                     |
| Dutch    | nl      | v2.4.3                     |
| Swedish  | sv      | v2.4.3                     |

{% hint style="info" %}
For more detailed information regarding the Dockerfile, please review the inline comments available in the GitHub repository.
{% endhint %}

### Docker Compose

You can use the docker image on the docker hub. It is using the same latest code as the folder "Docker" on the Github repo.

[icbest/giftmanager](https://hub.docker.com/r/icbest/giftmanager)

To use Docker Compose, copy, on your machine, the file [docker-compose.yml](https://github.com/icbestCA/giftmanager/blob/main/docker-compose.yml) from the repo.

You will need to edit the volume path to keep your data files in the correct folder.

```
volumes:
      - C:/Users/user1/documents/data:/app/data
```

Modify only this part `C:/Users/user1/documents/data` to mount the folder on your machine.\
When updating, keep the files where they are and just create a new container but mount it to the same folder on the host machine.

Edit the port you want to expose on the web.

```
ports:
      - "[port]:5000"
```

To run the container enter the directory of your docker-compose.yml file then in the terminal execute the following command:&#x20;

```
docker compose up -d && docker compose logs -f
```

You should see the image being pulled and the flask app being started.

For additionnal customization, see [Gunicorn Parameters](/getting-started/environnement-variables#docker-gunicorn-variables)

Now head to [setup](/getting-started/setup) and follow the steps to configure the app.

***

### Docker Run

You can use the docker image on the docker hub. It is using the same latest code as the folder "Docker" on the Github repo.

[icbest/giftmanager](https://hub.docker.com/r/icbest/giftmanager)&#x20;

Run the following command to run the container:

```
docker run -p [published-port]:5000 -d -v /path/to/data:/app/data --name giftmanager icbest/giftmanager 
```

Change the port on which you want to access, making the command like that:  80:5000  you could now access on port 80 in browser.

**Make sure** to add a path so the app can store the data on the host machine like that:&#x20;

Linux: `/root/data:/app/data`

Windows: `C:/Users/user1/documents/data:/app/data`

When updating, keep the files where they are and just create a new container but mount it to the same folder on the host machine.

For additionnal customization, see [Gunicorn Parameters](/getting-started/environnement-variables#docker-gunicorn-variables)

Now head to [setup](/getting-started/setup) and follow the steps to configure the app.

***

### Python Gunicorn (Linux Only)

**Make sure you have latest Python installed and Pip.**

1. Download the app folder in the [main repository](https://github.com/icbestCA/giftmanager).
2. Make sure to put the folder is unzipped and in a directory that make sense to you.
3. Inside the main directory, install requirements.txt with the following command:

```
pip install -r requirements.txt
```

4. Still inside the `app.py` directory run the command bellow to deploy in production with [Gunicorn](https://gunicorn.org/). You can access on port 80.

```
gunicorn app:app -w 1 --threads 4 -b 0.0.0.0:80 
```

Here the command `-w 1` : The number of workers, i recommend on 1 because using a json database it does some glitch with multiple workers. For faster loading time we use 4 threads which remains on one workers to prevent glitches. `-b 0.0.0.0:80`: The publish port, use port 80 so you can access it on default http. `app:app`: Define the file for the app.py .

6. Go to [setup ](/getting-started/setup)and follow the steps


# Environnement variables

### Docker Gunicorn variables

#### Can be set at container creation (v2.6.4 and up)

| Key               | what it does                                        | Default value |
| ----------------- | --------------------------------------------------- | ------------- |
| GUNICORN\_THREADS | The number of worker threads for handling requests. | 4             |
| GUNICORN\_BIND    | Chooses port inside the container                   | 0.0.0.0:5000  |

Example: `docker run -p 80:80 -e GUNICORN_THREADS=2 -e GUNICORN_THREADS=0.0.0.0:80 -v ./data:/app/data icbest/giftmanager`

### App Settings

#### Those settings can only be edited via the admin panel or directly in the .env in /data

<table><thead><tr><th>Key</th><th width="330">what it does</th><th>Default value</th></tr></thead><tbody><tr><td>SECRET_KEY</td><td>Used to secure session cookies.<br>Please change this value to your own.</td><td>changethis</td></tr><tr><td>MAILJET_API_KEY</td><td>Needed for emails on delete.<br>If not present, app will NOT try to contact mailjet servers.</td><td>[empty]</td></tr><tr><td>MAILJET_API_SECRET</td><td>Needed for emails on delete.</td><td>[empty]</td></tr><tr><td>SYSTEM_EMAIL</td><td>Email to send notification from.</td><td>[empty]</td></tr><tr><td>DELETE_DAYS</td><td>Days before auto-delete ideas bought<br><a href="/settings/deletion-script">See Deletion Script</a></td><td>30</td></tr><tr><td>OIDC_CLIENT_ID</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>[empty]</td></tr><tr><td>OIDC_CLIENT_SECRET</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>[empty]</td></tr><tr><td>OIDC_SERVER_METADATA_URL</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>[empty]</td></tr><tr><td>OIDC_LOGOUT_URL</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>[empty]</td></tr><tr><td>PRIMARY_OIDC_FIELD</td><td><a href="/settings/oidc-support#scopes-claims-and-database-field-mapping">See OIDC Support</a></td><td>email</td></tr><tr><td>SECONDARY_OIDC_FIELD</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>preferred_username</td></tr><tr><td>PRIMARY_DB_FIELD</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>email</td></tr><tr><td>SECONDARY_DB_FIELD</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>username</td></tr><tr><td>ENABLE_AUTO_REGISTRATION</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>false</td></tr><tr><td>ENABLE_DEFAULT_LOGIN</td><td><a href="/settings/oidc-support">See OIDC Support</a></td><td>true</td></tr><tr><td>LOGIN_PAGE_MESSAGE</td><td>Changes the message at the top of the login form. (Default will be empty in the .env because handled by the template)</td><td>No account? Contact a family member to create an account.</td></tr><tr><td>REORDERING</td><td>Allows reordering ideas on my_ideas page</td><td>true</td></tr><tr><td>IMGENABLED</td><td>Allows images in ideas (tries auto-fetch then ask user for link if failed)</td><td>false</td></tr><tr><td>CURRENCY_SYMBOL</td><td>Changes the symbol for the idea value</td><td>$</td></tr><tr><td>CURRENCY_POSITION</td><td>Changes the symbol position for the idea value</td><td>before</td></tr><tr><td>ENABLE_SELF_REGISTRATION</td><td>Allow people to self register on the login page.</td><td>false</td></tr><tr><td>JOINING_CODE</td><td>Needed to self register. (Empty will not ask for one at account creation)</td><td>[empty]</td></tr><tr><td>ENABLE_LINK_SHARING</td><td>Allows user to share their lists via external link.</td><td>true</td></tr></tbody></table>


# Setup

1. Head to the root URL `/`&#x20;
   1. **First Installation**: If this is your first time setting up the app, it will automatically generate the necessary files and restart to ensure these files are recognized.
   2. **Subsequent Runs**: If the required files are already mounted to the Docker container from a previous installation, the app will simply load the login page.
2. Once the app is ready, you will need to create the admin user. For that head to `/setupadmin` (or refresh the page after restarting) to create the admin user.
3. You can pre-configure most of environment variables.
4. Go to `/admin` (or use the button in the sidebar) you can then configure many parameters, see (settings list), make sure to restart the app after variables changes.


# Backups

## Backups

If you want to backup your data, you just need to copy the `users.json`  `ideas.json` and `.env`\
these are the only files containing the data.

#### Docker Backups <a href="#docker-backups" id="docker-backups"></a>

Backup the two files stored in the data folder mounted with the container.

#### Restore <a href="#restore" id="restore"></a>

If previous files exist they will be loaded in priority if located in the right same folder as mounted.


# Login

* Passwords are stored using `Argon2id` .
* Compare the hashed password and username (NOT case-sensitive) against entries in `users.json`.
* The `login.html` template show a banner with the instruction you entered at [Login Settings](/settings/login-settings). Will show errors messages if <mark style="color:red;">User does not exist</mark> or <mark style="color:red;">Wrong password</mark>.
* If an OIDC token is present in the .env there will be an OIDC button on the page.
* **Self-registration** is available in Advanced Settings. You can set a joining code that users must enter for their registration to be accepted. Leave the field blank if no code is required. A button will appear so people can self-register.
* **Guest users** will have a button appear so they can login using only a password.


# User Gift Ideas

* Each idea is in its own container with the following elements:
  * Title
  * Description
  * Estimated value in $ entered by the user
  * Added by (user who added the idea)
  * Button to mark as bought/not bought (with the buyer's name)
  * Delete and edit buttons (if the current user added the idea)
  * Link button (if provided)
* If no ideas are available, redirect to the `noidea` page.

> Note: If the current user is accessing their own list, redirect to `my_ideas` to prevent them from seeing which gifts others have bought or added for them.


# My Ideas

* Shows the ideas list from the connected user’s perspective.
* Only the connected user can view this page.
* Displays only the ideas added by the current user to keep other users’ contributions a surprise.
* The purchase status (bought or not) is hidden.
* The user can edit the priority of the ideas, using the `reorder` button and the drag-n-drop feature to change the priority number. They will be at top on the User Gift Ideas page.


# Users

On the users management page, you can edit each users properties, make them admin or delete them.

**\*\***&#x59;ou cannot revoke yourself from admin or delete your user.


# Secret Santa

1. **Navigate to** the Secret Santa page on the admin dashboard.
2. **Select Participants**: Choose the participants which will be randomly picked to give a gift to another participant.
3. **Add Pool Name**: Create multiple Secret Santa pools for different groups or families. Users can be part of multiple pools simultaneously. So give it a unique name like your family name.
4. **Add Instructions**: Include details such as average price, guidelines, and any other essential notes for participants.
5. **User Revelation**: Participants will see a new icon on their dashboard. Clicking this icon takes them to their assignment page (`/secret_santa_assignment`), where they’ll find out who they’re buying a gift for and the organizer’s instructions.
6. **Ending**: To conclude a Secret Santa event, go back to `/secret_santa`, choose the pool name, and click **Delete Pool** to remove it.

**Backend:**

* Each participant's assignment is stored in `users.json` in this format:

```
"assigned_users": {
            "pool1": "username2",
            "pool2": "username3"
}
```

* Instructions are saved in a new text file `santa_inst_<poolname>.txt` for easy reference.

<figure><img src="https://1258526111-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8RSJkhbo9dcBVf8AwPIX%2Fuploads%2F3S1xsFOlydJ9DJq02bkc%2Fsecret-santa.svg?alt=media&amp;token=fb626349-8995-4d2f-bc02-61199af1d971" alt=""><figcaption><p><strong>This icon</strong></p></figcaption></figure>


# Families

### Creating and Managing Groups <a href="#creating-and-managing-groups" id="creating-and-managing-groups"></a>

#### **Add a New Group**

To create a new group:

1. Use the **form** to enter the **group name**.
2. **Select at least one user** to be added to the group (a group cannot be created without users).
3. Click **Save** to create the group.

> **Note:** If a group is created without any users, it will be automatically deleted.

#### **Selecting Users for Groups**

* Use the **checkbox** next to each user's name to add them to a group.
* Users can be in **multiple groups**.

### Important Considerations <a href="#important-considerations" id="important-considerations"></a>

* **Users without a group** are visible to everyone and can see everyone.
* Only **admins** can access the group management page.
* Users in different groups can be accessed via a **direct URL**, but they **cannot be viewed through the app interface**.
* Always **save changes** after updating the permissions grid to ensure proper configuration.


# Guest Accounts

### Overview

Guest accounts provide limited access for users who only need to view gift lists and mark items as bought.\
This feature is ideal for relatives, friends, or others who should not be able to add or edit ideas.

***

### Features

* **Guest Passwords:** Create unique passwords for guests who need basic access.
* **View-Only Access:** Guests can view gift lists and mark items as bought.
* **Restricted Editing:** Guests cannot add, edit, or delete ideas.
* **Private Visibility:** Use *People Access* to assign which people or families a guest can see.
  * Each guest can have a private view of specific users or groups.

***

### Important Notes

> ⚠️ **Important:** Always manage guest accounts through the **Admin → Guest Users** page.\
> Do <mark style="color:$danger;">**not**</mark> *create, edit or delete* them through the standard **Users** page.

* Deleting a guest automatically removes all their associated data.
* Guests log in using the **“I have a guest password”** button on the login page.
* To ensure privacy between different guests, configure visibility using **People Access**.
  * This automatically creates private groups when needed.

***

### How to Create a Guest Account

1. Navigate to **Admin → Guest Users**.
2. Select which people or families the guest can see.
3. Set a password for the guest.
4. Share the password with the guest.
5. The guest can now log in using the **“I have a guest password”** option and view only the assigned lists.

***

### How It Works

The system automatically handles all group and access configurations in the background.\
Once a guest account is set up, permissions and visibility are applied automatically, no manual setup required.


# Shared Lists

#### **Features**

* **Multiple owners:** Any user assigned as an owner can edit and delete ideas in the list.
* **Not tied to a single user:** Ownership is shared, making the list suitable for team or group use.
* **Reordering limitations:** Due to implementation complexity, item reordering is currently **not supported** for shared lists.

#### **How to Create a Shared List**

1. Navigate to the **dashboard sidebar**.
2. Click on the **Shared Lists** link.
3. Create a new shared list.
4. Select the users who should have access and assign them as owners.


# Public Links

Public share links allow you to share any list you are a member of, personal or shared, using a secure, customizable link.

#### **Features**

* **Available for all list types:** You can create share links for both personal and shared lists.
  * For shared lists, *any* list member can manage its share links.
* **Customizable settings:**
  * Assign a name to each link
  * Set an expiration date
  * Choose whether visitors can mark items as purchased
* **Automatic protocol detection:**\
  Links automatically determine the correct HTTP protocol using the `X-Forwarded-Proto` header.

#### **Visitor Permissions**

* If purchase marking is enabled:
  * Visitors can mark gifts as bought.
  * They must enter a name before doing so.
  * Visitors can only undo purchases that *they* made, tracked locally in their browser.

#### **Administration & Management**

* **Global control:** Administrators can enable or disable public link functionality system-wide.
* **Per-link controls:** You can activate or deactivate individual share links at any time, and extend their expiration as needed.


# Admin Dashboard

* Only users with the admin status can access this.
* Most changes doesn't need any restart of the app to be applied, except OIDC and Email.


# Deletion Script

You can change the number of days before deleting the ideas. No need to restart after changing days.\
Also trigger the deletion manually&#x20;

Admin Dashboard > **Deletion Script**

Using `/rundl` you can automatically delete the ideas. (Mostly for automation's uses)


# Email Settings

This function allow to send notifications to buyers when ideas are removed while they bought it.

In the admin dashboard > **Email Settings** you can fill the Mailjet API keys and choose the email address used to send the notifications.

You need to restart the app to apply the changes.


# Login Settings

On this page you can edit the login message on the login form.

No need to restart the app after changing it.


# OIDC Support

OpenID connect allow you to connect to the app using a third-party auth provider like [Authelia](https://www.authelia.com/), [Authentik](https://goauthentik.io/), [keycloak ](https://www.keycloak.org/)and more. With OIDC, users only need to authenticate with the provider once to access all configured applications without additional passwords.

### Configuration

**After any changes you need to restart the app to apply them.** After entering the `client ID` the button for OIDC connection will appear on the login page. This uses the /login\_oidc route then call \
/auth for the verification.

#### Connection Setup

To configure OIDC, add the following values to the `.env` file, either using the admin dashboard or by manually editing the file which is in the mounted folder:

```
OIDC_CLIENT_ID=' '
OIDC_CLIENT_SECRET=' '
OIDC_SERVER_METADATA_URL=' '
OIDC_LOGOUT_URL=' '
```

You can find all those values quite easily in the provider's dashboard but here some hints: Server metadata URL usually end with this `/.well-known/openid-configuration` Logout URL usually end with this `/logout`

#### Scopes, Claims, and Database Field Mapping

The next parameters are used to compare the received values from the OIDC with the JSON users database.

```
PRIMARY_OIDC_FIELD='email'
SECONDARY_OIDC_FIELD='preferred_username'
PRIMARY_DB_FIELD='email'
SECONDARY_DB_FIELD='username'
```

These defaults are recommended but can be customized. Here are some common OIDC fields:

**OIDC**

You will need to confirm with the provider system but those are the most common used:

* given\_name (the full name)
* email (used to register in the provider)
* preferred\_username (username for login in the provider)

**JSON**

You can compare the previous values with the ones present in the JSON but under a different name.

* full\_name
* email
* username

The app will check for matching values in these fields and log in the user if there is a match.

#### Recommendations

Using the default field mappings is recommended, as they are widely supported. This setup compares values from the OIDC provider and the app's database to ensure that at least **one field** matches, allowing user login.

#### Auto Registration

If a user attempts to log in via OIDC and no matching fields are found, they can create a profile in the app. This will redirect them to `/setup_profile`, where they can provide any additional information not supplied by the OIDC provider, such as their birthday, avatar, and full name. Auto-registration is disabled by default but can be enabled by setting `ENABLE_AUTO_REGISTRATION=true` in the `.env` file.

#### Disable Login Form

To enforce OIDC for users, set the environment variable `ENABLE_DEFAULT_LOGIN` to `false`, allowing only the OIDC button to be displayed.


# Advanced

## Reordering Button

You can enable or disable the reordering button on the my\_ideas page.

## Images

This feature is still in beta mostly because of the placement within the app.\
You can try it by setting the value to *true*.

## Currency Settings

You can change the currency symbol to a custom value on the **Users’ Gift List** and **My Ideas** pages.\
By default, the **$** symbol appears before the amount (e.g., **$50**).\
You can use up to **5 characters** and choose whether the symbol appears **before or after** the amount.

There is **no space** by default, so if you want to use something like **USD**, you’ll need to **add a space manually** (e.g., **`USD` 50**).

You can **preview** the changes before applying them.

## Self-registration

Enable using checkbox, set joining code that people can enter on the page to see their registration accepted. Leave the field blank if no code is required. [For more information.](/features/login)

## Public links

Check the box to allow public lists sharing via customizable links.


