Skip to content

Commit

Permalink
Migrado para next 15, migrado para app router, migrado para login com…
Browse files Browse the repository at this point in the history
… JWT e removido sessão, salvando token no cookie
  • Loading branch information
erickweil committed Nov 11, 2024
1 parent a9c6a3d commit 7fd4166
Show file tree
Hide file tree
Showing 28 changed files with 5,772 additions and 3,783 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up environment
run: mv ./backend/.env.example ./backend/.env
run: |
mv ./backend/.env.example ./backend/.env
mv ./frontend/.env.production ./frontend/.env.local
- name: Extract metadata (tags, labels) for Docker
id: apimeta
Expand Down
845 changes: 735 additions & 110 deletions backend/package-lock.json

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,13 @@ const sessionParser = session(sessionOptions);
app.use(sessionParser);
*/

const tokenMiddleware = AuthManager.tokenMiddleware(false);
app.use(tokenMiddleware);
app.use(AuthManager.tokenMiddleware(false));
// Não. só vai ter sessão se estiver logado
// app.use(SessionManager.initSession);

// Websockets
if(WEBSOCKET_ENABLED) {
const wss = initWebSocketServer(server, tokenMiddleware);
const wss = initWebSocketServer(server, AuthManager.tokenMiddleware(false, true));
}

// Passando para o arquivo de rotas o app, que envia junto uma instância do express
Expand Down
44 changes: 27 additions & 17 deletions backend/src/middleware/authManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ export class AuthManager {
}
}

static tokenMiddleware(exigirLogin = true) {
static tokenMiddleware(exigirLogin = true, webSockets = false) {
return async (req, res, next) => {
try {
const auth = req.headers.authorization;
let auth;
if(webSockets) { // usado para testes e para quando é websockets apenas
let url = new URL(`http://localhost${req.url}`);
auth = url.searchParams.has("token") ? `Bearer ${url.searchParams.get("token")}` : undefined;
} else {
auth = req.headers.authorization;
}

if (!auth) {
// Se essa rota não EXIGE que seja feito login, não tem problema...
Expand Down Expand Up @@ -122,21 +128,26 @@ export class AuthManager {
// An identifier for the user, unique among all Google accounts and never reused. A Google account can have multiple email addresses at different points in time, but the sub value is never changed. Use sub within your application as the unique-identifier key for the user. Maximum length of 255 case-sensitive ASCII characters.
//session.username = userinfo.sub;
//session.save();
const tokenPayload = {
username: userinfo.sub,
name: userinfo.name,
picture: userinfo.picture,
};
const token = await promisify(jwt.sign)(
{
username: userinfo.sub,
name: userinfo.name
},
SESSION_SECRET,
{
expiresIn: SESSION_MAX_AGE // expressed in seconds or a string describing a time span
}
);

// Para retornar o tempo de expiração
const {decoded, error} = await AuthManager._decodeJWTToken(token);
if (error) {
throw new Error(error);
}

return {
payload: tokenPayload,
token: await promisify(jwt.sign)(
tokenPayload,
SESSION_SECRET,
{
expiresIn: SESSION_MAX_AGE // expressed in seconds or a string describing a time span
}
)
token: token,
payload: decoded
};
}

Expand All @@ -150,8 +161,7 @@ export class AuthManager {
} else {
return {
username: "anonimo",
name: "Anônimo",
picture: null
name: "Anônimo"
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions backend/src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { LOG_ROUTES } from "../config/options.js";
export const logRoutes = (req,res,next) => {
const timestamp = new Date().toISOString();

const username = req.session?.username || "anonimo";
const name = req.tokenPayload?.name || "anonimo";

let ip = req.headers["x-forwarded-for"] ||
req.socket.remoteAddress ||
null;

console.log(timestamp+" "+ip+" "+username+" "+req.protocol + "://" + req.get("host") + req.originalUrl);
console.log(timestamp+" "+ip+" "+name+" "+req.protocol + "://" + req.get("host") + req.originalUrl);
next();
};

Expand Down
63 changes: 45 additions & 18 deletions backend/src/websocket/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,26 +72,53 @@ const initWebSocketServer = (server, tokenMiddleware) => {
const wss = new WebSocketServer({server});

wss.on("connection", (ws, req) => {
ws.isAlive = true;

ws.on("error",(error) => {
console.log("Erro em:"+ws.username,error);
});
ws.on("pong", () => {
//console.log("Recebeu pong de "+ws.session.username);
try {
ws.isAlive = true;
});
ws.on("close", () => {
console.log(ws.username+" desconectou.");
});

tokenMiddleware(req, {}, function() {
ws.tokenPayload = req.tokenPayload;
ws.username = req.tokenPayload?.username || haiku();
console.log(ws.username+" conectado.");

onConnection(wss,ws);
});
ws.on("error",(error) => {
console.log("Erro em:"+ws.username,error);
});
ws.on("pong", () => {
//console.log("Recebeu pong de "+ws.session.username);
ws.isAlive = true;
});
ws.on("close", () => {
console.log(ws.username+" desconectou.");
});

const mockRes = {
status: (code) => {
mockRes.code = code;
return mockRes;
},
json: (obj) => {
throw new Error(JSON.stringify(obj));
}
};

tokenMiddleware(req, mockRes, function() {
ws.tokenPayload = req.tokenPayload;
ws.username = req.tokenPayload?.name || haiku();
console.log(ws.username+" conectado.");

onConnection(wss,ws);
}).catch((error) => {
console.error("Erro ao autenticar websocket:",error);
try {
ws.close();
} catch(ee) {
console.error("Erro ao fechar websocket:",ee);
}
});
} catch(e) {
console.error("Erro ao conectar websockets:",e);

try {
ws.close();
} catch(ee) {
console.error("Erro ao fechar websocket:",ee);
}
}
});

// Ping https://www.npmjs.com/package/ws#how-to-detect-and-close-broken-connections
Expand Down
3 changes: 1 addition & 2 deletions backend/test/pixels.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import RedisMock from "../src/controller/redisMock.js";

const session = {
username: "teste",
name: "Teste",
picture: null
name: "Teste"
};

// Poderia utilizar o supertest, mas já que o controller é separado chamar ele direto vai dar
Expand Down
6 changes: 4 additions & 2 deletions frontend/.env.development
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
SERVERSIDE_API_URL="http://127.0.0.1:3001"
NEXT_PUBLIC_API_URL="http://localhost:3000/backend"

NEXT_PUBLIC_WEB_URL="http://localhost:3000"
NEXT_PUBLIC_API_URL="http://localhost:3001"

# Websockets
NEXT_PUBLIC_WEBSOCKET_ENABLED="true"
NEXT_PUBLIC_WEBSOCKET_URL="ws://localhost:3000/backend/"
NEXT_PUBLIC_WEBSOCKET_URL="ws://localhost:3001/"
# Especifica o caminho que irá buscar os assets, para
# hospedar o site em um subpath /algumacoisa
ASSET_PREFIX=""
Expand Down
1 change: 1 addition & 0 deletions frontend/.env.production
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
SERVERSIDE_API_URL="http://weilplace-api:80"

NEXT_PUBLIC_WEB_URL="https://weilplace.app.fslab.dev"
NEXT_PUBLIC_API_URL="https://weilplace.app.fslab.dev/backend"

NEXT_PUBLIC_WEBSOCKET_ENABLED="true"
Expand Down
2 changes: 0 additions & 2 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ USER nextjs
EXPOSE 3000

ENV PORT 3000
# set hostname to localhost
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

Expand Down
1 change: 1 addition & 0 deletions frontend/jsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"jsx": "react",
"paths": {
"@/*": ["./src/*"]
}
Expand Down
62 changes: 31 additions & 31 deletions frontend/next.config.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: "standalone",
assetPrefix: process.env.ASSET_PREFIX || undefined,
webpack: (config,options) => {
// Solve compiling problem via vagrant
config.watchOptions = {
poll: 1000, // Check for changes every second
aggregateTimeout: 300, // delay before rebuilding
ignored: ['**/node_modules','**/.git','**/.next'],
};
return config;
}
}

// Testes apenas
if(process.env.NODE_ENV === "development") {
nextConfig.rewrites = async () => {
return {
fallback: [
{
source: "/backend/:path*",
destination: `${process.env.SERVERSIDE_API_URL}/:path*`,
},
],
};
};
}

module.exports = nextConfig
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: "standalone",
assetPrefix: process.env.ASSET_PREFIX || undefined,
webpack: (config,options) => {
// Solve compiling problem via vagrant
config.watchOptions = {
poll: 1000, // Check for changes every second
aggregateTimeout: 300, // delay before rebuilding
ignored: ['**/node_modules','**/.git','**/.next'],
};
return config;
}
}

// Testes apenas
if(process.env.NODE_ENV === "development") {
nextConfig.rewrites = async () => {
return {
fallback: [
{
source: "/backend/:path*",
destination: `${process.env.SERVERSIDE_API_URL}/:path*`,
},
],
};
};
}

module.exports = nextConfig
Loading

0 comments on commit 7fd4166

Please sign in to comment.