mirror of
https://github.com/suitenumerique/meet.git
synced 2026-07-26 11:58:53 +00:00
wip use a transit token
This commit is contained in:
@@ -50,8 +50,8 @@ function startPolling(session_id, { onSuccess, onTimeout, onError }) {
|
||||
|
||||
// ─── Transit Dialog ───────────────────────────────────────────────────────
|
||||
|
||||
function openTransitDialog(session_id, { onCancel, onError }) {
|
||||
const meetUrl = `${BASE_URL}/addons/transit/?session_id=${session_id}`;
|
||||
function openTransitDialog(transit_token, { onCancel, onError }) {
|
||||
const meetUrl = `${BASE_URL}/addons/transit/?transit_token=${transit_token}`;
|
||||
|
||||
Office.context.ui.displayDialogAsync(
|
||||
meetUrl,
|
||||
@@ -92,6 +92,7 @@ function connect() {
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
const session_id = data.session_id;
|
||||
const transit_token = data.transit_token;
|
||||
setStatus("En attente d'authentification...");
|
||||
|
||||
const pollInterval = startPolling(session_id, {
|
||||
@@ -109,7 +110,7 @@ function connect() {
|
||||
},
|
||||
});
|
||||
|
||||
openTransitDialog(session_id, {
|
||||
openTransitDialog(transit_token, {
|
||||
onCancel: () => clearInterval(pollInterval),
|
||||
onError: (err) => {
|
||||
clearInterval(pollInterval);
|
||||
|
||||
@@ -35,7 +35,7 @@ class TokenExchangeService:
|
||||
secret_key=settings.ADDONS_JWT_SECRET_KEY,
|
||||
algorithm=settings.ADDONS_JWT_ALG,
|
||||
issuer=settings.ADDONS_JWT_ISSUER,
|
||||
audience=settings.ADDONS_JWT_AUDIENCE,
|
||||
audience=settings.ADDONS_JWT_AUDIENCE, # todo - precise
|
||||
expiration_seconds=settings.ADDONS_JWT_EXPIRATION_SECONDS,
|
||||
token_type=settings.ADDONS_JWT_TOKEN_TYPE,
|
||||
)
|
||||
@@ -48,7 +48,7 @@ class TokenExchangeService:
|
||||
"""Wip."""
|
||||
return f"{settings.ADDONS_SESSION_TOKEN_PREFIX}_{result_token}"
|
||||
|
||||
def init_session(self) -> tuple[str, str]:
|
||||
def init_session(self) -> tuple[str, str, str]:
|
||||
"""Create a new pending authentication session and return its ID."""
|
||||
|
||||
session_id = secrets.token_urlsafe(settings.ADDONS_SESSION_ID_LENGTH)
|
||||
@@ -77,10 +77,18 @@ class TokenExchangeService:
|
||||
timeout=settings.ADDONS_SESSION_TIMEOUT,
|
||||
)
|
||||
|
||||
print('$$ init session_id')
|
||||
print(session_id)
|
||||
# Transit token → session_id, very short TTL, one-time use
|
||||
transit_token = secrets.token_urlsafe(32)
|
||||
cache.set(
|
||||
f"addon_transit_{transit_token}",
|
||||
session_id,
|
||||
timeout=120
|
||||
)
|
||||
|
||||
return session_id, result_token
|
||||
print('$$ init transit_token')
|
||||
print(transit_token)
|
||||
|
||||
return session_id, result_token, transit_token
|
||||
|
||||
# todo - wip
|
||||
def get_session(self, session_id: str) -> dict:
|
||||
@@ -174,3 +182,11 @@ class TokenExchangeService:
|
||||
def token_to_session(self, result_token):
|
||||
"""wip."""
|
||||
return None
|
||||
|
||||
def consume_transit_token(self, transit_token: str) -> str | None:
|
||||
"""Resolve and immediately delete the transit token (one-time use)."""
|
||||
key = f"addon_transit_{transit_token}"
|
||||
session_id = cache.get(key)
|
||||
if session_id:
|
||||
cache.delete(key) # consumed — cannot be replayed
|
||||
return session_id
|
||||
|
||||
@@ -18,13 +18,18 @@ def render_error(request, message, status=400):
|
||||
def transit_page(request):
|
||||
"""Initialize authentication flow for add-on session."""
|
||||
|
||||
session_id = request.GET.get("session_id")
|
||||
transit_token = request.GET.get("transit_token")
|
||||
|
||||
if not transit_token:
|
||||
return render_error(request, _("Transit token is required."), status=400)
|
||||
|
||||
session_id = TokenExchangeService().consume_transit_token(transit_token)
|
||||
|
||||
if not session_id:
|
||||
return render_error(request, _("Session ID is required."), status=400)
|
||||
return render_error(request, _("Invalid or expired transit token."), status=404)
|
||||
|
||||
# Validate the session is still pending
|
||||
data = TokenExchangeService().get_session(session_id)
|
||||
|
||||
if not data:
|
||||
return render_error(request, _("Session not found or expired."), status=404)
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ class AuthSessionViewSet(viewsets.ViewSet):
|
||||
Returns session_id in the body (client forwards it to the 3rd-party view).
|
||||
Sets result_token as an HttpOnly cookie (the only poll credential).
|
||||
"""
|
||||
session_id, result_token = TokenExchangeService().init_session()
|
||||
session_id, result_token, transit_token = TokenExchangeService().init_session()
|
||||
response = drf_response.Response(
|
||||
{"session_id": session_id}, status=drf_status.HTTP_201_CREATED
|
||||
{"session_id": session_id, "transit_token": transit_token}, status=drf_status.HTTP_201_CREATED
|
||||
)
|
||||
response.set_cookie(
|
||||
key=settings.ADDONS_RESULT_TOKEN_COOKIE_NAME,
|
||||
|
||||
Reference in New Issue
Block a user