diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 4172073..fcf1fea 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -40,6 +40,7 @@ jobs: uses: 73h/gae-app-yaml-replace-env-variables@v0.1 env: POSTGRES_STRING: ${{ secrets.POSTGRES_STRING }} + PROJECT_ID: ${{ secrets.PROJECT_ID }} with: app_yaml_path: app.yaml diff --git a/README.md b/README.md index c450dc2..1087a36 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ This API provides endpoints for interacting with two main tables: `faucet.solana 3. Set up your `.env` file with the following ```env POSTGRES_STRING=postgresql://:@:/ + PROJECT_ID= ``` 4. Start the server diff --git a/app.js b/app.js index 64d4b98..e09c8a6 100644 --- a/app.js +++ b/app.js @@ -1,15 +1,13 @@ -// Importing Express and Routes using ES Module syntax import express from 'express'; -import routes from './src/routes/index.js'; // Must include the .js extension in ES Modules +import routes from './src/routes/index.js'; +import { validateGoogleToken } from './src/routes/middleware/authorization.js'; // Initialize Express const app = express(); // Middleware app.use(express.json()); // Parse JSON request bodies - -// Routes -app.use('/api', routes); // Use routes from the /routes folder +app.use('/api', validateGoogleToken, routes); // Secure all API routes // Global Error Handling Middleware app.use((err, req, res, next) => { diff --git a/app.yaml b/app.yaml index 0c737e2..3032047 100644 --- a/app.yaml +++ b/app.yaml @@ -12,6 +12,7 @@ entrypoint: yarn start # Environment variables (replace with your actual values or secrets) env_variables: POSTGRES_STRING: $POSTGRES_STRING + PROJECT_ID: $PROJECT_ID # Automatic scaling configuration automatic_scaling: diff --git a/package.json b/package.json index a6a97e5..784b44d 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "dotenv": "^16.4.5", "express": "^4.21.1", + "google-auth-library": "^9.14.2", "pg": "^8.13.1" } } diff --git a/src/routes/middleware/authorization.js b/src/routes/middleware/authorization.js new file mode 100644 index 0000000..f1265bc --- /dev/null +++ b/src/routes/middleware/authorization.js @@ -0,0 +1,29 @@ +import { OAuth2Client } from 'google-auth-library'; + +const oAuth2Client = new OAuth2Client(); + +const validateGoogleToken = async (req, res, next) => { + const authHeader = req.header('Authorization'); + if (!authHeader) { + return res.status(401).json({ message: 'Unauthorized' }); + } + + const token = authHeader.split(' ')[1]; // Bearer + try { + // Verify the access token's payload: + const tokenInfo = await oAuth2Client.getTokenInfo(token); + + if (tokenInfo.email !== `solana-devnet-faucet-fe@${process.env.PROJECT_ID}.iam.gserviceaccount.com`) { + return res.status(403).json({ message: 'Forbidden: Invalid audience' }); + } + + // Proceed if valid token + req.user = tokenInfo; // Attach tokenInfo data (like subject) to req.user + next(); + } catch (error) { + console.log("Error with Auth", error); + res.status(403).json({ message: 'Forbidden' }); + } +}; + +export { validateGoogleToken }; \ No newline at end of file