Repository: inventree/InvenTree

Issue:
Language settings not saved
### Please verify that this bug has NOT been raised before.

- [X] I checked and didn't find similar issue

### Describe the bug*

Each time I startup firefox and log on inventree I have to change the language settings.


### Steps to Reproduce

I use a computer and browser set in french but I want inventree to use english.

1. Start up browser
2. Log in inventree => Inventree use french
3. Change to english => Inventree use english
4. Close browser
5. Start up browser
6. Log in inventree => Inventree still use french


### Expected behavior

Whenever I log on Inventree, language setting should be kept

### Deployment Method

- [x] Docker
- [ ] Bare metal

### Version Information

0.8.3

### Relevant log output

_No response_
Language settings not saved
### Please verify that this bug has NOT been raised before.

- [X] I checked and didn't find similar issue

### Describe the bug*

Each time I startup firefox and log on inventree I have to change the language settings.


### Steps to Reproduce

I use a computer and browser set in french but I want inventree to use english.

1. Start up browser
2. Log in inventree => Inventree use french
3. Change to english => Inventree use english
4. Close browser
5. Start up browser
6. Log in inventree => Inventree still use french


### Expected behavior

Whenever I log on Inventree, language setting should be kept

### Deployment Method

- [x] Docker
- [ ] Bare metal

### Version Information

0.8.3

### Relevant log output

_No response_


Discussion:
@AlexandrePTJ thanks for reporting. I have not been able to reproduce this.

Can you confirm that you are changing the language setting via the "settings" menu as below?

![image](https://user-images.githubusercontent.com/10080325/192651809-2a77f9c2-ad5c-4f7c-9269-87b059f19229.png)

Does the selected language change by itself back to the previous value/
Yes I do.
Sorry I checked "Bare metal" for the installation, but it is "docker"
- Can you test if the problem persists for any other languages?
- Do any other settings get "reset" when you log out and log back in?
* Just tested with german, italiano and norsk : it always come back to french
* Yes I did change some search settings and they have reset.
Just take note that settings are reset when I close and restart the browser, not when I logout/login.
Is your browser locale configured to request french language? I think it will use the browser request header language if provided.
You are right when I change my browser settings, Inventree display the language I set in firefox. Then if now I select in Inventree french and restart my browser it came back to english ;)
Also I see thaht when I change another settings, I see this in the logs:
```
inventree-server-1  | 09:43:09 [Q] INFO Enqueued 36641
inventree-proxy-1   | 172.18.0.2 - - [28/Sep/2022:07:43:09 +0000] "PATCH /api/settings/user/STICKY_HEADER/ HTTP/1.1" 200 210 "http://inventree.moby.home.lan/settings/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0" "10.66.0.3"
inventree-worker-1  | 09:43:09 [Q] INFO Process-1:1 processing [william-low-kentucky-apart]
inventree-worker-1  | 09:43:10 [Q] INFO Processed [william-low-kentucky-apart]
```

But this kind of requests does not appears when I change language settings.
Sounds like everything is working as intended then :)
Not really. I mean, whatever my browser's settings are, I should be able to use another language settings in Inventree. This is not the case. I will not switch my browser language everytime I login on Inventree.
@AlexandrePTJ this is how django (the framework we use) prioritizes language lookup:

https://docs.djangoproject.com/en/4.1/topics/i18n/translation/#how-django-discovers-language-preference

@matmair any comments on this one? IIRC you had a lot to do with the language selection stuff
From the django doc, using browser language is right after using session cookie. So If cookie is set, language should be kept to user selection.
@SchrodingersGat we use the default stuff offered by Django; not sure what could break there. You can set Firefox to enforce a specific language and Django will respect that. Maybe that is what is going on in this edgecase.

I checked with Firefox on macOS and Windows and can not reproduce this.
@matmair thanks for checking!

@AlexandrePTJ are you able to test with a different browser and/or computer?
I did reprodruce on mac, linux and windows. With firefox and any other browser.
Is there any public instance of Inventree I could try on ? I may come from my installation, but I don't see any error or warning message telling language settings is not saved.
@AlexandrePTJ you can try on https://demo.inventree.org - please check here and report back
I have the exact same behaviour:
1. Login with engineer account. Display is in French.
2. Go to settings, change language to English. Display is in English.
3. Close the browser (not only the tab)
4. Login with engineer account. Display is back in French.
I can replicate this in edge browser, but it seems to work *as expected* in chrome.

@AlexandrePTJ what browsers have you tried this with?
I tried with safari on mac and with firefox on either linux and windows.
Also just tried with chrome (fresh install) on windows and I also get the issue.
@AlexandrePTJ can you check if the session cookie is set in your browser?
![image](https://user-images.githubusercontent.com/10080325/195069336-de769628-c2d7-4294-8cab-081230a01995.png)

e.g. when changing language to italian, I see the following cookie
Yes cookie is changed. But it looks to expires at session. So if session ends (closing browser) cookies expires. No ?
The cookie should persist. I have tested locally, and the cookie is persistent when:

- Logging out / in
- Closing the browser

(at least on chrome)

Can you confirm that the cookie resets when you close and re-open the browser?
@SchrodingersGat @AlexandrePTJ this sounds like firefox is limiting the cookie lifetime. It tends to do that if it is set to more privacy-conscious presets.
@SchrodingersGat I confirm that the cookie resets.
@matmair Then it depends on which kind of cookie this settings is written. Attached a screenshot of cookie used by another django based application (weblate)
<img width="959" alt="Sans titre" src="https://user-images.githubusercontent.com/3862081/195310276-eb1d4260-bd98-4368-b836-6b7ca3461a4b.png">

This seems to be a client (/browser) issue and not related to InvenTree.
I checked with firefox 105 on MacOS, Debian and Windows again and it works as expected on the latest stable and latest master.
@AlexandrePTJ
1A) Could you try turning off privacy protections for the instance you are having problems with?
1B) Is your instance hosted with HTTPS? That might limit how long the browser stores the cookie
1C) You never posted the full version info; Could you post the Version presented in the `About` section? there should be a copy button there
A) Turning off privacy settings did not change anything. Not a good approach anyway :)
B) No, only http
C) Sorry I missed this point:

```
# Version Information:
InvenTree-Version: 0.8.3
Django Version: 3.2.15
Commit Hash: f9d2b14
Commit Date: 2022-09-23
Database: postgresql
Debug-Mode: False
Deployed using Docker: True
```

I dig a bit into django documention and into weblate code too understand how weblate does to make it works.
This settings [LANGUAGE_COOKIE_AGE](https://docs.djangoproject.com/en/3.2/ref/settings/#language-cookie-age) tooks my attention. I added `LANGUAGE_COOKIE_AGE = 12096000` into `InvenTree/settings.py`, then everything is working perfectly.
@AlexandrePTJ very interesting, I wonder why the cookie is *not* being deleted otherwise then. Nice work figuring this out
@AlexandrePTJ PR to fix this is in review now.
@AlexandrePTJ thanks for reporting. I have not been able to reproduce this.

Can you confirm that you are changing the language setting via the "settings" menu as below?

![image](https://user-images.githubusercontent.com/10080325/192651809-2a77f9c2-ad5c-4f7c-9269-87b059f19229.png)

Does the selected language change by itself back to the previous value/
Yes I do.
Sorry I checked "Bare metal" for the installation, but it is "docker"
- Can you test if the problem persists for any other languages?
- Do any other settings get "reset" when you log out and log back in?
* Just tested with german, italiano and norsk : it always come back to french
* Yes I did change some search settings and they have reset.
Just take note that settings are reset when I close and restart the browser, not when I logout/login.
Is your browser locale configured to request french language? I think it will use the browser request header language if provided.
You are right when I change my browser settings, Inventree display the language I set in firefox. Then if now I select in Inventree french and restart my browser it came back to english ;)
Also I see thaht when I change another settings, I see this in the logs:
```
inventree-server-1  | 09:43:09 [Q] INFO Enqueued 36641
inventree-proxy-1   | 172.18.0.2 - - [28/Sep/2022:07:43:09 +0000] "PATCH /api/settings/user/STICKY_HEADER/ HTTP/1.1" 200 210 "http://inventree.moby.home.lan/settings/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0" "10.66.0.3"
inventree-worker-1  | 09:43:09 [Q] INFO Process-1:1 processing [william-low-kentucky-apart]
inventree-worker-1  | 09:43:10 [Q] INFO Processed [william-low-kentucky-apart]
```

But this kind of requests does not appears when I change language settings.
Sounds like everything is working as intended then :)
Not really. I mean, whatever my browser's settings are, I should be able to use another language settings in Inventree. This is not the case. I will not switch my browser language everytime I login on Inventree.
@AlexandrePTJ this is how django (the framework we use) prioritizes language lookup:

https://docs.djangoproject.com/en/4.1/topics/i18n/translation/#how-django-discovers-language-preference

@matmair any comments on this one? IIRC you had a lot to do with the language selection stuff
From the django doc, using browser language is right after using session cookie. So If cookie is set, language should be kept to user selection.
@SchrodingersGat we use the default stuff offered by Django; not sure what could break there. You can set Firefox to enforce a specific language and Django will respect that. Maybe that is what is going on in this edgecase.

I checked with Firefox on macOS and Windows and can not reproduce this.
@matmair thanks for checking!

@AlexandrePTJ are you able to test with a different browser and/or computer?
I did reprodruce on mac, linux and windows. With firefox and any other browser.
Is there any public instance of Inventree I could try on ? I may come from my installation, but I don't see any error or warning message telling language settings is not saved.
@AlexandrePTJ you can try on https://demo.inventree.org - please check here and report back
I have the exact same behaviour:
1. Login with engineer account. Display is in French.
2. Go to settings, change language to English. Display is in English.
3. Close the browser (not only the tab)
4. Login with engineer account. Display is back in French.
I can replicate this in edge browser, but it seems to work *as expected* in chrome.

@AlexandrePTJ what browsers have you tried this with?
I tried with safari on mac and with firefox on either linux and windows.
Also just tried with chrome (fresh install) on windows and I also get the issue.
@AlexandrePTJ can you check if the session cookie is set in your browser?
![image](https://user-images.githubusercontent.com/10080325/195069336-de769628-c2d7-4294-8cab-081230a01995.png)

e.g. when changing language to italian, I see the following cookie
Yes cookie is changed. But it looks to expires at session. So if session ends (closing browser) cookies expires. No ?
The cookie should persist. I have tested locally, and the cookie is persistent when:

- Logging out / in
- Closing the browser

(at least on chrome)

Can you confirm that the cookie resets when you close and re-open the browser?
@SchrodingersGat @AlexandrePTJ this sounds like firefox is limiting the cookie lifetime. It tends to do that if it is set to more privacy-conscious presets.
@SchrodingersGat I confirm that the cookie resets.
@matmair Then it depends on which kind of cookie this settings is written. Attached a screenshot of cookie used by another django based application (weblate)
<img width="959" alt="Sans titre" src="https://user-images.githubusercontent.com/3862081/195310276-eb1d4260-bd98-4368-b836-6b7ca3461a4b.png">

This seems to be a client (/browser) issue and not related to InvenTree.
I checked with firefox 105 on MacOS, Debian and Windows again and it works as expected on the latest stable and latest master.
@AlexandrePTJ
1A) Could you try turning off privacy protections for the instance you are having problems with?
1B) Is your instance hosted with HTTPS? That might limit how long the browser stores the cookie
1C) You never posted the full version info; Could you post the Version presented in the `About` section? there should be a copy button there
A) Turning off privacy settings did not change anything. Not a good approach anyway :)
B) No, only http
C) Sorry I missed this point:

```
# Version Information:
InvenTree-Version: 0.8.3
Django Version: 3.2.15
Commit Hash: f9d2b14
Commit Date: 2022-09-23
Database: postgresql
Debug-Mode: False
Deployed using Docker: True
```

I dig a bit into django documention and into weblate code too understand how weblate does to make it works.
This settings [LANGUAGE_COOKIE_AGE](https://docs.djangoproject.com/en/3.2/ref/settings/#language-cookie-age) tooks my attention. I added `LANGUAGE_COOKIE_AGE = 12096000` into `InvenTree/settings.py`, then everything is working perfectly.
@AlexandrePTJ very interesting, I wonder why the cookie is *not* being deleted otherwise then. Nice work figuring this out
@AlexandrePTJ PR to fix this is in review now.

Resolving patch:
diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py
--- a/InvenTree/InvenTree/settings.py
+++ b/InvenTree/InvenTree/settings.py
@@ -607,6 +607,8 @@
 # Internationalization
 # https://docs.djangoproject.com/en/dev/topics/i18n/
 LANGUAGE_CODE = get_setting('INVENTREE_LANGUAGE', 'language', 'en-us')
+# Store language settings for 30 days
+LANGUAGE_COOKIE_AGE = 2592000
 
 # If a new language translation is supported, it must be added here
 LANGUAGES = [


Test patch: