Skip to content

Commit de06454

Browse files
fix(auth): filter Telegram JWKS for Supabase OIDC
Supabase Auth go-jose rejects secp256k1 in Telegram JWKS (github.com/supabase/auth/issues/2534). Serve filtered discovery. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 143a2ea commit de06454

3 files changed

Lines changed: 134 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"issuer": "https://oauth.telegram.org",
3+
"authorization_endpoint": "https://oauth.telegram.org/auth",
4+
"token_endpoint": "https://oauth.telegram.org/token",
5+
"jwks_uri": "https://frontchapter.ir/oidc/telegram-jwks.json",
6+
"response_types_supported": [
7+
"code"
8+
],
9+
"token_endpoint_auth_methods_supported": [
10+
"client_secret_basic",
11+
"client_secret_post"
12+
],
13+
"subject_types_supported": [
14+
"public"
15+
],
16+
"id_token_signing_alg_values_supported": [
17+
"RS256",
18+
"ES256",
19+
"EdDSA"
20+
],
21+
"scopes_supported": [
22+
"openid",
23+
"phone",
24+
"profile",
25+
"telegram:bot_access"
26+
],
27+
"claims_supported": [
28+
"aud",
29+
"preferred_username",
30+
"phone_number",
31+
"exp",
32+
"iat",
33+
"iss",
34+
"name",
35+
"picture",
36+
"sub"
37+
],
38+
"code_challenge_methods_supported": [
39+
"plain",
40+
"S256"
41+
],
42+
"grant_types_supported": [
43+
"authorization_code"
44+
]
45+
}

‎public/oidc/telegram-jwks.json‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"keys": [
3+
{
4+
"alg": "RS256",
5+
"e": "AQAB",
6+
"ext": true,
7+
"key_ops": [
8+
"verify"
9+
],
10+
"kty": "RSA",
11+
"n": "5RneLtsKvVcxdv6gu6gxEQu30Cru5NiMQnY6SNr9ZyZFZ4ya-pfHNuaZXJ6QPG0JSFwoxeOkEO2-eZN_REVPm448PvjjsR1eQdZ5QpEkNxnItFcmxkHH91v5cgf52_EI9BGO-MT6f1vaBSg3uWHFlDxI7J2AYxNvd1_Nf3TkgrrR7gyJFTmEIai5RefGnA0KGNYDlRIGUzrz2F05n6gTaHFT_iHL5UHatTZA4GCiUSjIOuwqu5pE5uZge20TFv3cxXMQaFw_xv1pgQt_Rq8eoCN7TS0RQ0zjWKiad-W286BcFectXsUm03p5Nq_kY4mf_7rqwX_B8yy_bBreyKn7RQ",
12+
"kid": "oidc-1"
13+
},
14+
{
15+
"alg": "ES256",
16+
"kty": "EC",
17+
"x": "ahVYrohhX6YA7w0P2gUNSwMFbaabCgBZFkeq9bWdmwU",
18+
"y": "Ea8nKJ34VQMA7zv8aYDfzcBhXEjnWQ9C06jVke_eUV0",
19+
"crv": "P-256",
20+
"kid": "oidc-es256-1",
21+
"use": "sig"
22+
},
23+
{
24+
"alg": "EdDSA",
25+
"crv": "Ed25519",
26+
"x": "i6BEafXMEe4osXgUTffpKAm6Cn6F2bhqPZoclunTAV4",
27+
"kty": "OKP",
28+
"kid": "oidc-eddsa-1",
29+
"use": "sig"
30+
}
31+
]
32+
}

‎scripts/refresh-telegram-oidc.py‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python3
2+
"""Refresh filtered Telegram JWKS (drops secp256k1 — breaks Supabase Auth go-jose).
3+
4+
Run: python3 scripts/refresh-telegram-oidc.py
5+
Then deploy. Point Supabase custom:telegram Discovery URL at:
6+
https://frontchapter.ir/oidc/telegram-discovery.json
7+
Issuer stays: https://oauth.telegram.org
8+
"""
9+
from __future__ import annotations
10+
11+
import gzip
12+
import json
13+
import ssl
14+
from pathlib import Path
15+
from urllib.request import Request, urlopen
16+
17+
ROOT = Path(__file__).resolve().parents[1] / "public" / "oidc"
18+
OUT_DISC = ROOT / "telegram-discovery.json"
19+
OUT_JWKS = ROOT / "telegram-jwks.json"
20+
SITE_JWKS = "https://frontchapter.ir/oidc/telegram-jwks.json"
21+
22+
23+
def get(url: str) -> dict:
24+
req = Request(url, headers={"Accept": "application/json", "Accept-Encoding": "gzip"})
25+
with urlopen(req, context=ssl.create_default_context(), timeout=30) as r:
26+
data = r.read()
27+
if r.headers.get("Content-Encoding") == "gzip" or data[:2] == b"\x1f\x8b":
28+
data = gzip.decompress(data)
29+
return json.loads(data.decode("utf-8"))
30+
31+
32+
def main() -> None:
33+
disc = get("https://oauth.telegram.org/.well-known/openid-configuration")
34+
jwks = get("https://oauth.telegram.org/.well-known/jwks.json")
35+
filtered = {
36+
"keys": [
37+
k
38+
for k in jwks["keys"]
39+
if k.get("crv") != "secp256k1" and k.get("alg") != "ES256K"
40+
]
41+
}
42+
disc = dict(disc)
43+
disc["jwks_uri"] = SITE_JWKS
44+
disc["id_token_signing_alg_values_supported"] = [
45+
a
46+
for a in disc.get("id_token_signing_alg_values_supported", [])
47+
if a != "ES256K"
48+
]
49+
ROOT.mkdir(parents=True, exist_ok=True)
50+
OUT_DISC.write_text(json.dumps(disc, indent=2) + "\n")
51+
OUT_JWKS.write_text(json.dumps(filtered, indent=2) + "\n")
52+
print("kept", [k.get("kid") for k in filtered["keys"]])
53+
print("wrote", OUT_DISC, OUT_JWKS)
54+
55+
56+
if __name__ == "__main__":
57+
main()

0 commit comments

Comments
 (0)