1tube 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/gateway/auth.ts +37 -0
package/package.json
CHANGED
package/src/gateway/auth.ts
CHANGED
|
@@ -165,11 +165,48 @@ async function verifyToken(token: string): Promise<JWTPayload | null> {
|
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
167
|
* Validate the Authorization header and return an AuthContext, or null if invalid.
|
|
168
|
+
*
|
|
169
|
+
* Two accepted token forms:
|
|
170
|
+
*
|
|
171
|
+
* 1. **HMAC-SHA256 JWT** signed with `JWT_SECRET`. This is the primary auth
|
|
172
|
+
* mechanism — used by user session tokens and (in hosted Supabase) by
|
|
173
|
+
* service role calls, since hosted service role keys are themselves JWTs.
|
|
174
|
+
*
|
|
175
|
+
* 2. **Service role key passthrough.** When `SUPABASE_SERVICE_ROLE_KEY` is set
|
|
176
|
+
* and the bearer token matches it exactly, the request is treated as a
|
|
177
|
+
* service-role call. This lets local-dev deployments use opaque key formats
|
|
178
|
+
* (e.g. `sb_secret_*`) for inter-function calls without minting JWTs.
|
|
179
|
+
*
|
|
180
|
+
* The synthesised payload has `role: "service_role"` and an empty `sub`,
|
|
181
|
+
* matching the shape produced by hosted Supabase. Authorization specs that
|
|
182
|
+
* want service-only access should check for `payload.role === "service_role"`
|
|
183
|
+
* (e.g. via `require: ["service_role"]`).
|
|
168
184
|
*/
|
|
169
185
|
export async function validateRequest(req: Request): Promise<AuthContext | null> {
|
|
170
186
|
const token = parseBearer(req.headers.get("Authorization"));
|
|
171
187
|
if (!token) return null;
|
|
172
188
|
|
|
189
|
+
const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") || "";
|
|
190
|
+
if (serviceKey && token === serviceKey) {
|
|
191
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
192
|
+
return {
|
|
193
|
+
userId: "",
|
|
194
|
+
email: "",
|
|
195
|
+
payload: {
|
|
196
|
+
sub: "",
|
|
197
|
+
email: "",
|
|
198
|
+
role: "service_role",
|
|
199
|
+
iss: "supabase",
|
|
200
|
+
aud: "service_role",
|
|
201
|
+
iat: nowSec,
|
|
202
|
+
// Synthetic exp matching JWTPayload shape; the token has no real
|
|
203
|
+
// expiry of its own — rotation is governed by env reload.
|
|
204
|
+
exp: nowSec + 60 * 60,
|
|
205
|
+
},
|
|
206
|
+
rawToken: token,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
173
210
|
const payload = await verifyToken(token);
|
|
174
211
|
if (!payload) return null;
|
|
175
212
|
|