~xenrox/10man-web

835ca88cd2da75117884caa330166afa8162d68d — Marius Riedl 9 months ago 9aa4ca2 master
Add auth to UI
7 files changed, 79 insertions(+), 16 deletions(-)

M .env
M README.md
M server/app.ts
M src/components/Header.vue
M src/router/index.ts
M src/views/Home.vue
A src/views/Index.vue
M .env => .env +3 -1
@@ 1,4 1,6 @@
PORT=8080
BASE_URL=http://localhost
SECRET_COOKIE=<SECURE_PASSWORD>
STEAM_API_KEY=<STEAM_API_KEY>
\ No newline at end of file
STEAM_API_KEY=<STEAM_API_KEY>

VUE_APP_SERVER_URL=http://localhost:8081
\ No newline at end of file

M README.md => README.md +1 -1
@@ 26,7 26,7 @@ yarn build
yarn lint
```

### UI/Server Structure
## UI/Server Structure

The 10man-web application consists of two parts, front-end UI and front-end server.
The UI lives on a port configured as an environment variable, the server on the subsequent one.

M server/app.ts => server/app.ts +15 -10
@@ 1,15 1,16 @@
import express from "express";
import session from "express-session";
import dotenv from "dotenv";
import cors from "cors";
import cookieParser from "cookie-parser";
import { v4 as uuidv4 } from "uuid";
import dotenv from "dotenv";
import passport from "./auth/passport";

dotenv.config();

const clientPort = process.env.PORT!;
const serverPort = Number(process.env.PORT)! + 1;
const clientUrl = process.env.BASE_URL! + ":" + clientPort;
let clientUrl = process.env.BASE_URL! + ":" + clientPort;

const app = express();
const env = app.get("env");


@@ 24,19 25,27 @@ const sessionOptions = {
};

if (env === "production") {
  clientUrl = process.env.BASE_URL!;
  app.set("trust proxy", 1);
  sessionOptions.cookie.secure = true;
}

const authenticate = (req: any, res: any, next: any) => {
  if (!req.user) {
    res.redirect("/auth/forbidden");
    res.status(401).send();
  } else {
    next();
  }
};

app.set("port", serverPort);
app.use(
  cors({
    origin: clientUrl,
    credentials: true,
    exposedHeaders: ["set-cookie"],
  }),
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(process.env.SECRET_COOKIE));


@@ 59,21 68,17 @@ app.get(
  passport.authenticate("steam", { failureRedirect: "/auth/login" }),
  (req, res) => {
    // Redirect to index
    res.redirect(clientUrl);
    res.redirect(clientUrl + "/#/home");
  },
);

app.get("/auth/active", authenticate, (req, res) => {
  res.send(true);
});

app.get("/auth/logout", authenticate, (req, res) => {
  req.logout();
  res.redirect(clientUrl);
});

app.get("/auth/forbidden", (req, res) => {
  res.send("Not authenticated");
app.get("/user", authenticate, (req, res) => {
  res.status(200).send(req.user);
});

export default app;

M src/components/Header.vue => src/components/Header.vue +2 -1
@@ 2,7 2,8 @@
  <div class="header">
    <router-link to="/">Header</router-link>
    <div class="actions">
      <a href="http://localhost:8081/auth/login">Steam login</a>
      <a href="http://localhost:8081/auth/login">Steam login</a> |
      <a href="http://localhost:8081/auth/logout">Logout</a>
    </div>
  </div>
</template>

M src/router/index.ts => src/router/index.ts +9 -0
@@ 1,12 1,21 @@
import Vue from "vue";
import VueRouter, { RouteConfig } from "vue-router";
import axios from "axios";
import Index from "../views/Index.vue";
import Home from "../views/Home.vue";

Vue.use(VueRouter);

axios.defaults.withCredentials = true;

const routes: Array<RouteConfig> = [
  {
    path: "/",
    name: "Index",
    component: Index,
  },
  {
    path: "/home",
    name: "Home",
    component: Home,
  },

M src/views/Home.vue => src/views/Home.vue +17 -3
@@ 1,17 1,31 @@
<template>
  <div class="home">
    <div class="introduction">{{ msg }}</div>
    <div class="message">{{ msg }}</div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import axios from "axios";

@Component({
  components: {},
})
export default class Home extends Vue {
  msg = "Welcome to 10-Man\nPlease sign in/sign up via Steam";
  msg = "Welcome to 10-Man\nYou are logged in";
  user = {};

  created(): void {
    this.getUser();
  }

  async getUser(): Promise<void> {
    await axios
      .get(process.env.VUE_APP_SERVER_URL + "/user")
      .then((res) => (this.user = res.data))
      .then(() => localStorage.setItem("user", JSON.stringify(this.user)))
      .catch(() => this.$router.push("/"));
  }
}
</script>



@@ 21,7 35,7 @@ export default class Home extends Vue {
  flex-direction: column;
  flex-grow: 1;

  .introduction {
  .message {
    color: #fff;
    width: fit-content;
    position: relative;

A src/views/Index.vue => src/views/Index.vue +32 -0
@@ 0,0 1,32 @@
<template>
  <div class="index">
    <div class="introduction">{{ msg }}</div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component({
  components: {},
})
export default class Index extends Vue {
  msg = "Welcome to 10-Man\nPlease sign in/sign up via Steam";
}
</script>

<style lang="scss" scoped>
.index {
  display: flex;
  flex-direction: column;
  flex-grow: 1;

  .introduction {
    color: #fff;
    width: fit-content;
    position: relative;
    top: 10em;
    left: 10em;
  }
}
</style>