Skip to content

Instantly share code, notes, and snippets.

@arthuro555
Created July 12, 2024 16:36
Show Gist options
  • Save arthuro555/dfd66f49c7de70532ee2c98a34afd340 to your computer and use it in GitHub Desktop.
Save arthuro555/dfd66f49c7de70532ee2c98a34afd340 to your computer and use it in GitHub Desktop.
GDevelop Firebase Auth server
import { Hono } from "https://deno.land/x/hono@v4.1.5/mod.ts";
import { cors } from "https://deno.land/x/hono@v4.1.5/middleware.ts";
import { decode } from "https://deno.land/x/djwt/mod.ts";
const FIREBASE_SECRET = Deno.env.get("FIREBASE_SECRET");
const ALLOWED_GAME_IDS = new Set(["<Your Game ID>"]);
const app = new Hono();
let id = 0;
let FIREBASE_PARSED_SECRET;
try {
FIREBASE_PARSED_SECRET = JSON.parse(FIREBASE_SECRET);
} catch {
throw new Error("Firebase secret is not valid JSON!");
}
app.post("/login", async (c) => {
const token = await c.req.text();
const [, payload] = decode(token);
const { sub: gameId, aud: playerId } = payload;
if (!ALLOWED_GAME_IDS.has(gameId)) return c.text("Invalid game ID", 400);
const { isValidPlayerToken } = await (await fetch(
`https://api.gdevelop.io/authorization/game/${gameId}/action/verify-player-token`,
{method: "POST", body: JSON.stringify({
playerId,
playerAuthorizationHeader: `player-game-token ${token}`,
})}
)).json();
if(!isValidPlayerToken) {
c.status(403);
return c.text("Unauthorized");
}
const userProfile = await fetch(`https://api.gdevelop.io/user/user-public-profile/${playerId}`)
const { username, iconUrl } = await userProfile.json();
const { initializeApp, cert, deleteApp } = await import(
"npm:firebase-admin@12.0.0/app"
);
const { getAuth } = await import("npm:firebase-admin@12.0.0/auth");
const f = initializeApp(
{
credential: cert(FIREBASE_PARSED_SECRET),
},
"" + id++
);
const auth = getAuth(f);
try {
await auth.updateUser(playerId, {
displayName: username,
photoURL: iconUrl,
});
} catch {
await auth.createUser({
uid: playerId,
displayName: username,
email: `${encodeURIComponent(username)}-${playerId}@players.gdevelop.io`,
emailVerified: false,
photoURL: iconUrl,
});
}
const firebaseToken = await auth.createCustomToken(playerId);
deleteApp(f);
return c.text(firebaseToken);
});
Deno.serve(app.fetch);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment