Remove cookies (#1223)

This commit is contained in:
Elijah Ahianyo 2023-06-28 01:04:29 +00:00 committed by GitHub
parent c6c4410db5
commit be48e13c71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 18 deletions

View File

@ -17,6 +17,9 @@ let token;
// Key for the token in the session storage.
const TOKEN_KEY = "token";
// create cookie instance
const cookies = new Cookies();
// Dictionary holding component references.
export const refs = {};
@ -114,9 +117,12 @@ export const applyEvent = async (event, router, socket) => {
}
if (event.name == "_set_cookie") {
const cookies = new Cookies();
cookies.set(event.payload.key, event.payload.value);
localStorage.setItem(event.payload.key, event.payload.value);
return false;
}
if (event.name == "_remove_cookie") {
cookies.remove(event.payload.key, event.payload.options)
return false;
}

View File

@ -23,6 +23,7 @@ from .event import EventChain as EventChain
from .event import FileUpload as upload_files
from .event import console_log as console_log
from .event import redirect as redirect
from .event import remove_cookie as remove_cookie
from .event import set_clipboard as set_clipboard
from .event import set_cookie as set_cookie
from .event import set_focus as set_focus

View File

@ -240,8 +240,8 @@ def set_cookie(key: str, value: str) -> EventSpec:
"""Set a cookie on the frontend.
Args:
key (str): The key identifying the cookie.
value (str): The value contained in the cookie.
key: The key identifying the cookie.
value: The value contained in the cookie.
Returns:
EventSpec: An event to set a cookie.
@ -254,12 +254,30 @@ def set_cookie(key: str, value: str) -> EventSpec:
)
def remove_cookie(key: str, options: Dict[str, Any] = {}) -> EventSpec: # noqa: B006
"""Remove a cookie on the frontend.
Args:
key: The key identifying the cookie to be removed.
options: Support all the cookie options from RFC 6265
Returns:
EventSpec: An event to remove a cookie.
"""
return server_side(
"_remove_cookie",
get_fn_signature(remove_cookie),
key=key,
options=options,
)
def set_local_storage(key: str, value: str) -> EventSpec:
"""Set a value in the local storage on the frontend.
Args:
key (str): The key identifying the variable in the local storage.
value (str): The value contained in the local storage.
key: The key identifying the variable in the local storage.
value: The value contained in the local storage.
Returns:
EventSpec: An event to set a key-value in local storage.

View File

@ -5,7 +5,9 @@ import asyncio
import copy
import functools
import inspect
import json
import traceback
import urllib.parse
from abc import ABC
from collections import defaultdict
from typing import (
@ -351,7 +353,7 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
"""Initialize a variable.
Args:
prop (BaseVar): The variable to initialize
prop: The variable to initialize
Raises:
TypeError: if the variable has an incorrect type
@ -496,15 +498,21 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
Returns:
The dict of cookies.
"""
headers = self.get_headers().get(constants.RouteVar.COOKIE)
return (
{
pair[0].strip(): pair[1].strip()
for pair in (item.split("=") for item in headers.split(";"))
}
if headers
else {}
)
cookie_dict = {}
cookies = self.get_headers().get(constants.RouteVar.COOKIE, "").split(";")
cookie_pairs = [cookie.split("=") for cookie in cookies if cookie]
for pair in cookie_pairs:
key, value = pair[0].strip(), urllib.parse.unquote(pair[1].strip())
try:
# cast non-string values to the actual types.
value = json.loads(value)
except json.JSONDecodeError:
pass
finally:
cookie_dict[key] = value
return cookie_dict
@classmethod
def setup_dynamic_args(cls, args: dict[str, str]):

View File

@ -452,7 +452,10 @@ def router_data_headers() -> Dict[str, str]:
"sec-websocket-version": "13",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"cookie": "csrftoken=mocktoken; name=reflex",
"cookie": "csrftoken=mocktoken; "
"name=reflex;"
" list_cookies=%5B%22some%22%2C%20%22random%22%2C%20%22cookies%22%5D;"
" dict_cookies=%7B%22name%22%3A%20%22reflex%22%7D; val=true",
"sec-websocket-key": "mock-websocket-key",
"sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
}

View File

@ -1,3 +1,5 @@
import json
import pytest
from reflex import event
@ -160,6 +162,35 @@ def test_set_cookie():
)
def test_remove_cookie():
"""Test the event remove_cookie."""
spec = event.remove_cookie("testkey")
assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_remove_cookie"
assert spec.args == (("key", "testkey"), ("options", {}))
assert (
format.format_event(spec) == 'E("_remove_cookie", {key:"testkey",options:{}})'
)
def test_remove_cookie_with_options():
"""Test the event remove_cookie with options."""
options = {
"path": "/",
"domain": "example.com",
"secure": True,
"sameSite": "strict",
}
spec = event.remove_cookie("testkey", options)
assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_remove_cookie"
assert spec.args == (("key", "testkey"), ("options", options))
assert (
format.format_event(spec)
== f'E("_remove_cookie", {{key:"testkey",options:{json.dumps(options)}}})'
)
def test_set_local_storage():
"""Test the event set_local_storage."""
spec = event.set_local_storage("testkey", "testvalue")

View File

@ -737,7 +737,13 @@ def test_get_cookies(test_state, mocker, router_data):
"""
mocker.patch.object(test_state, "router_data", router_data)
assert test_state.get_cookies() == {"csrftoken": "mocktoken", "name": "reflex"}
assert test_state.get_cookies() == {
"csrftoken": "mocktoken",
"name": "reflex",
"list_cookies": ["some", "random", "cookies"],
"dict_cookies": {"name": "reflex"},
"val": True,
}
def test_get_current_page(test_state):