Skip to content

Commit

Permalink
feat(authentification): integrated auth0 into frontend and backend, b…
Browse files Browse the repository at this point in the history
…ut backend pard needs to be tested and fixed in the future
  • Loading branch information
Dedakup committed Nov 22, 2024
1 parent 5caaf5d commit f64abc7
Show file tree
Hide file tree
Showing 30 changed files with 4,937 additions and 1,067 deletions.
2 changes: 2 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules
.serverless
.env
.env.local
5,302 changes: 4,427 additions & 875 deletions backend/package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
"joi": "^17.13.3",
"jsonwebtoken": "^7.4.3",
"jwk-to-pem": "^1.2.6",
"jwks-rsa": "^3.1.0",
"request": "^2.88.2",
"serverless-webpack": "^5.15.0",
"uuid": "^11.0.3"
},
"devDependencies": {
"eslint": "^9.15.0",
"jest": "^29.7.0",
"prettier": "^3.3.3"
"prettier": "^3.3.3",
"serverless-offline": "^14.3.4"
}
}
123 changes: 57 additions & 66 deletions backend/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@ org: devquesting
app: focusflow
service: backend

plugins:
- serverless-offline


provider:
name: aws
runtime: nodejs20.x
region: us-east-1
stage: dev
environment:
AUTH0_DOMAIN: your-auth0-domain.auth0.com
AUTH0_AUDIENCE: focusflow-audience
AUTH0_ISSUER: https://dev-6zeb418i7xs8g1lc.us.auth0.com/
DYNAMODB_TASKS_TABLE: ${self:custom.tableName}
DYNAMODB_USERS_TABLE: ${self:custom.usersTableName}
S3_ASSETS_BUCKET: ${self:custom.bucketName}
ISSUER_URL: "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_kUSQwBwuo"
iam:
role:
statements:
Expand All @@ -34,6 +40,10 @@ provider:
- s3:GetObject
- s3:DeleteObject
Resource: !Join ["/", [!GetAtt AssetsBucket.Arn, "*"]]
- Effect: Allow
Action:
- cognito-idp:SignUp
Resource: '*'

custom:
tableName: ${sls:stage}-focusflow-tasks
Expand Down Expand Up @@ -84,87 +94,88 @@ resources:
AllowedOrigins: ["*"]
MaxAge: 3000

# Cognito User Pool
UserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: ${sls:stage}-focusflow-users
AutoVerifiedAttributes:
- email
UsernameAttributes:
- email
Policies:
PasswordPolicy:
MinimumLength: 8
RequireLowercase: true
RequireNumbers: true
RequireSymbols: true
RequireUppercase: true

# Cognito User Pool Client
UserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: ${sls:stage}-focusflow-client
UserPoolId:
Ref: UserPool
ExplicitAuthFlows:
- ALLOW_USER_SRP_AUTH
- ALLOW_REFRESH_TOKEN_AUTH
GenerateSecret: false

functions:
# Task Management
createTask:
handler: src/handlers/task.createTask
handler: src/handlers/task/createTask.createTask
events:
- http:
path: tasks
method: post
cors: true
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer
getTasks:
handler: src/handlers/task.getTasks
handler: src/handlers/task/getTasks.getTasks
events:
- http:
path: tasks
method: get
cors: true
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer
updateTask:
handler: src/handlers/task.updateTask
handler: src/handlers/task/updateTask.updateTask
events:
- http:
path: tasks/{taskId}
method: put
cors: true
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer
deleteTask:
handler: src/handlers/task.deleteTask
handler: src/handlers/task/deleteTask.deleteTask
events:
- http:
path: tasks/{taskId}
method: delete
cors: true
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer

# Pomodoro Timer
manageTimer:
handler: src/handlers/timer.manageTimer
handler: src/handlers/timer/manageTimer.manageTimer
events:
- http:
path: timer
method: post
cors: true
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer

# User Preferences
updatePreferences:
handler: src/handlers/preferences.updatePreferences
handler: src/handlers/preferences/updatePreferences.updatePreferences
events:
- http:
path: preferences
method: put
cors: true
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer

# Music Player
getMusic:
handler: src/handlers/music.getMusic
handler: src/handlers/music/getMusic.getMusic
events:
- http:
path: music
Expand All @@ -173,37 +184,17 @@ functions:

# Background Management
updateBackground:
handler: src/handlers/background.updateBackground
handler: src/handlers/background/updateBackground.updateBackground
events:
- http:
path: backgrounds
method: put
cors: true

# Authentication
login:
handler: src/handlers/auth.login
events:
- http:
path: auth/login
method: post
cors: true
signup:
handler: src/handlers/auth.signup
events:
- http:
path: auth/signup
method: post
cors: true
verifyToken:
handler: src/handlers/auth.verifyToken
events:
- http:
path: auth/verify
method: post
cors: true


# Custom Authorizer
auth:
handler: src/handlers/auth.authorize
authorizer:
type: REQUEST
identitySource: method.request.header.Authorization
authorizerResultTtlInSeconds: 300
name: auth0Authorizer

auth0Authorizer:
handler: src/handlers/auth/auth.auth0Authorizer
69 changes: 0 additions & 69 deletions backend/src/handlers/auth.js

This file was deleted.

56 changes: 56 additions & 0 deletions backend/src/handlers/auth/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const jwt = require("jsonwebtoken");
const jwksClient = require("jwks-rsa");

const client = jwksClient({
jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`,
});

function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
}

module.exports.auth0Authorizer = async (event) => {
const token = event.headers.Authorization || event.headers.authorization;

if (!token) {
return {
statusCode: 401,
body: JSON.stringify({ message: "Unauthorized" }),
};
}

const bearerToken = token.split(" ")[1];

try {
const decoded = await new Promise((resolve, reject) => {
jwt.verify(
bearerToken,
getKey,
{ audience: process.env.AUTH0_AUDIENCE, issuer: process.env.AUTH0_ISSUER },
(err, decoded) => (err ? reject(err) : resolve(decoded))
);
});

return {
principalId: decoded.sub,
policyDocument: {
Version: "2012-10-17",
Statement: [
{
Action: "execute-api:Invoke",
Effect: "Allow",
Resource: event.methodArn,
},
],
},
};
} catch (err) {
return {
statusCode: 401,
body: JSON.stringify({ message: "Unauthorized" }),
};
}
};
20 changes: 20 additions & 0 deletions backend/src/handlers/background/updateBackground.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const db = require('../../utils/db');

module.exports.updateBackground = async (event) => {
const userId = event.requestContext.authorizer.userId;
const { background } = JSON.parse(event.body);

const params = {
TableName: process.env.DYNAMODB_USERS_TABLE,
Key: { userId },
UpdateExpression: 'set background = :background',
ExpressionAttributeValues: { ':background': background },
};

await db.update(params);

return {
statusCode: 200,
body: JSON.stringify({ message: 'Background updated successfully' }),
};
};
Empty file removed backend/src/handlers/handler.js
Empty file.
11 changes: 11 additions & 0 deletions backend/src/handlers/music/getMusic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports.getMusic = async () => {
const musicList = [
{ id: 1, title: 'Lo-Fi Beats', url: 'https://example.com/music1.mp3' },
{ id: 2, title: 'Chill Vibes', url: 'https://example.com/music2.mp3' },
];

return {
statusCode: 200,
body: JSON.stringify(musicList),
};
};
Loading

0 comments on commit f64abc7

Please sign in to comment.