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. // Key for the token in the session storage.
const TOKEN_KEY = "token"; const TOKEN_KEY = "token";
// create cookie instance
const cookies = new Cookies();
// Dictionary holding component references. // Dictionary holding component references.
export const refs = {}; export const refs = {};
@ -114,9 +117,12 @@ export const applyEvent = async (event, router, socket) => {
} }
if (event.name == "_set_cookie") { if (event.name == "_set_cookie") {
const cookies = new Cookies();
cookies.set(event.payload.key, event.payload.value); 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; return false;
} }

View File

@ -23,6 +23,7 @@ from .event import EventChain as EventChain
from .event import FileUpload as upload_files from .event import FileUpload as upload_files
from .event import console_log as console_log from .event import console_log as console_log
from .event import redirect as redirect 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_clipboard as set_clipboard
from .event import set_cookie as set_cookie from .event import set_cookie as set_cookie
from .event import set_focus as set_focus 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. """Set a cookie on the frontend.
Args: Args:
key (str): The key identifying the cookie. key: The key identifying the cookie.
value (str): The value contained in the cookie. value: The value contained in the cookie.
Returns: Returns:
EventSpec: An event to set a cookie. 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: def set_local_storage(key: str, value: str) -> EventSpec:
"""Set a value in the local storage on the frontend. """Set a value in the local storage on the frontend.
Args: Args:
key (str): The key identifying the variable in the local storage. key: The key identifying the variable in the local storage.
value (str): The value contained in the local storage. value: The value contained in the local storage.
Returns: Returns:
EventSpec: An event to set a key-value in local storage. EventSpec: An event to set a key-value in local storage.

View File

@ -5,7 +5,9 @@ import asyncio
import copy import copy
import functools import functools
import inspect import inspect
import json
import traceback import traceback
import urllib.parse
from abc import ABC from abc import ABC
from collections import defaultdict from collections import defaultdict
from typing import ( from typing import (
@ -351,7 +353,7 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
"""Initialize a variable. """Initialize a variable.
Args: Args:
prop (BaseVar): The variable to initialize prop: The variable to initialize
Raises: Raises:
TypeError: if the variable has an incorrect type TypeError: if the variable has an incorrect type
@ -496,15 +498,21 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
Returns: Returns:
The dict of cookies. The dict of cookies.
""" """
headers = self.get_headers().get(constants.RouteVar.COOKIE) cookie_dict = {}
return ( cookies = self.get_headers().get(constants.RouteVar.COOKIE, "").split(";")
{
pair[0].strip(): pair[1].strip() cookie_pairs = [cookie.split("=") for cookie in cookies if cookie]
for pair in (item.split("=") for item in headers.split(";"))
} for pair in cookie_pairs:
if headers key, value = pair[0].strip(), urllib.parse.unquote(pair[1].strip())
else {} 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 @classmethod
def setup_dynamic_args(cls, args: dict[str, str]): 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", "sec-websocket-version": "13",
"accept-encoding": "gzip, deflate, br", "accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9", "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-key": "mock-websocket-key",
"sec-websocket-extensions": "permessage-deflate; client_max_window_bits", "sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
} }

View File

@ -1,3 +1,5 @@
import json
import pytest import pytest
from reflex import event 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(): def test_set_local_storage():
"""Test the event set_local_storage.""" """Test the event set_local_storage."""
spec = event.set_local_storage("testkey", "testvalue") 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) 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): def test_get_current_page(test_state):