Skip to content

Commit

Permalink
Added idToken creation server
Browse files Browse the repository at this point in the history
  • Loading branch information
ihsraham committed Oct 20, 2024
1 parent 9f9992e commit f467d39
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 200 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@auth0/auth0-react": "^2.2.4",
"@orbs-network/ton-access": "^2.3.3",
"@telegram-apps/sdk-react": "^2.0.6",
"@telegram-apps/types": "^1.0.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,73 @@ const path = require("path");
const { AuthDataValidator } = require("@telegram-auth/server");
const { objectToAuthDataMap } = require("@telegram-auth/server/utils");
const RateLimit = require("express-rate-limit");
const cors = require('cors');

dotenv.config();

const app = express();
app.use(express.json()); // Middleware to parse JSON requests

// Rate limiter configuration: limit to 100 requests per 15 minutes
const { TELEGRAM_BOT_TOKEN, SERVER_URL, JWT_KEY_ID } = process.env;
const privateKey = fs.readFileSync(path.resolve(__dirname, "privateKey.pem"), "utf8");

// CORS configuration
const corsOptions = {
origin: SERVER_URL,
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'],
};

// Apply CORS middleware to all routes
app.use(cors(corsOptions));

// Handle preflight requests for all routes
app.options('*', cors(corsOptions));

// Rate limiter configuration
const limiter = RateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: "Too many requests from this IP, please try again later."
});

// Apply rate limiter to all routes
app.use(limiter);

const { TELEGRAM_BOT_TOKEN, SERVER_URL, JWT_KEY_ID } = process.env;

// Read private key for JWT signing
const privateKey = fs.readFileSync(path.resolve(__dirname, "privateKey.pem"), "utf8");

// Helper function to generate JWT token using the Telegram user data
// Helper function to generate JWT token
const generateJwtToken = (userData) => {
const payload = {
telegram_id: userData.id,
username: userData.username,
avatar_url: userData.photo_url,
sub: userData.id.toString(), // Subject is the user ID
name: userData.first_name, // Full name if you want to include
iss: "https://api.telegram.org", // Issuer is your server URL
iat: Math.floor(Date.now() / 1000), // Issued at time
exp: Math.floor(Date.now() / 1000) + 60 * 60, // Expires in 1 hour
sub: userData.id.toString(),
name: userData.first_name,
iss: "https://api.telegram.org",
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 60 * 60,
};

return jwt.sign(payload, privateKey, { algorithm: "RS256", keyid: JWT_KEY_ID });
};

// Default route to check if the server is running
app.get("/", (req, res) => res.send("Express on Vercel for Telegram Login to be used with Web3Auth"));

// Serving the JWKS for verifying JWT signature
app.get("/.well-known/jwks.json", (req, res) => {
const jwks = fs.readFileSync(path.resolve(__dirname, "jwks.json"), "utf8");
res.json(JSON.parse(jwks)); // Return JWKS JSON file
});

// Endpoint to validate Telegram data and generate JWT
// Validate Telegram data and generate JWT
app.post("/auth/telegram", async (req, res) => {
const { initDataRaw } = req.body; // Get initDataRaw from the request body
const { initDataRaw } = req.body;

if (!initDataRaw) {
return res.status(400).json({ error: "initDataRaw is required" });
}

const validator = new AuthDataValidator({ botToken: TELEGRAM_BOT_TOKEN });
const data = objectToAuthDataMap(new URLSearchParams(initDataRaw)); // Parse initDataRaw
const data = objectToAuthDataMap(new URLSearchParams(initDataRaw));

try {
// Validate Telegram data
const user = await validator.validate(data);

// Generate a JWT token
const JWTtoken = generateJwtToken(user);

// Send back the JWT token to the client
res.json({ token: JWTtoken });
} catch (error) {
console.error("Error validating Telegram data:", error);
res.status(400).json({ error: "Invalid Telegram data" });
}
});

// Server listening on port 3000 (or replace with your Vercel/Heroku port settings)
app.listen(3000, () => console.log("Server ready on port 3000."));

module.exports = app;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"author": "",
"dependencies": {
"@telegram-auth/server": "^1.0.3",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-rate-limit": "^7.4.0",
Expand All @@ -15,7 +16,7 @@
"name": "sfa-web-ton-telegram-server",
"scripts": {
"lint": "eslint",
"start": "node index.js",
"start": "node api/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "1.0.0",
Expand Down
4 changes: 4 additions & 0 deletions single-factor-auth-web/sfa-web-ton-telegram-example/src/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
VITE_SERVER_URL="" # server-url
VITE_W3A_VERIFIER_NAME="" # w3a-verifier-name
VITE_W3A_CLIENT_ID="" # w3a-client-id from web3auth dashboard
REACT_APP_SERVER_URL="http://localhost:3000" # server-url
Loading

0 comments on commit f467d39

Please sign in to comment.