Page de profil #13

Manually merged
wpetit merged 3 commits from feature/user-profile into develop 2020-07-17 09:25:52 +02:00
16 changed files with 349 additions and 46 deletions
Showing only changes of commit 8b8f322630 - Show all commits

198
client/package-lock.json generated
View File

@ -1230,8 +1230,7 @@
"@types/node": {
"version": "13.13.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.12.tgz",
"integrity": "sha512-zWz/8NEPxoXNT9YyF2osqyA9WjssZukYpgI4UYZpOjcyqwIUqWGkcCionaEb9Ki+FULyPyvNFpg/329Kd2/pbw==",
"dev": true
"integrity": "sha512-zWz/8NEPxoXNT9YyF2osqyA9WjssZukYpgI4UYZpOjcyqwIUqWGkcCionaEb9Ki+FULyPyvNFpg/329Kd2/pbw=="
},
"@types/prop-types": {
"version": "15.7.3",
@ -1372,6 +1371,11 @@
}
}
},
"@types/zen-observable": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz",
"integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg=="
},
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@ -1547,6 +1551,23 @@
"@xtuc/long": "4.2.2"
}
},
"@wry/context": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/@wry/context/-/context-0.4.4.tgz",
"integrity": "sha512-LrKVLove/zw6h2Md/KZyWxIkFM6AoyKp71OqpH9Hiip1csjPVoD3tPxlbQUNxEnHENks3UGgNpSBCAfq9KWuag==",
"requires": {
"@types/node": ">=6",
"tslib": "^1.9.3"
}
},
"@wry/equality": {
"version": "0.1.11",
"resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz",
"integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==",
"requires": {
"tslib": "^1.9.3"
}
},
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -1723,6 +1744,93 @@
}
}
},
"apollo-cache": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.3.5.tgz",
"integrity": "sha512-1XoDy8kJnyWY/i/+gLTEbYLnoiVtS8y7ikBr/IfmML4Qb+CM7dEEbIUOjnY716WqmZ/UpXIxTfJsY7rMcqiCXA==",
"requires": {
"apollo-utilities": "^1.3.4",
"tslib": "^1.10.0"
}
},
"apollo-cache-inmemory": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.6.6.tgz",
"integrity": "sha512-L8pToTW/+Xru2FFAhkZ1OA9q4V4nuvfoPecBM34DecAugUZEBhI2Hmpgnzq2hTKZ60LAMrlqiASm0aqAY6F8/A==",
"requires": {
"apollo-cache": "^1.3.5",
"apollo-utilities": "^1.3.4",
"optimism": "^0.10.0",
"ts-invariant": "^0.4.0",
"tslib": "^1.10.0"
}
},
"apollo-client": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.6.10.tgz",
"integrity": "sha512-jiPlMTN6/5CjZpJOkGeUV0mb4zxx33uXWdj/xQCfAMkuNAC3HN7CvYDyMHHEzmcQ5GV12LszWoQ/VlxET24CtA==",
"requires": {
"@types/zen-observable": "^0.8.0",
"apollo-cache": "1.3.5",
"apollo-link": "^1.0.0",
"apollo-utilities": "1.3.4",
"symbol-observable": "^1.0.2",
"ts-invariant": "^0.4.0",
"tslib": "^1.10.0",
"zen-observable": "^0.8.0"
}
},
"apollo-link": {
"version": "1.2.14",
"resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz",
"integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==",
"requires": {
"apollo-utilities": "^1.3.0",
"ts-invariant": "^0.4.0",
"tslib": "^1.9.3",
"zen-observable-ts": "^0.8.21"
}
},
"apollo-link-http": {
"version": "1.5.17",
"resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.17.tgz",
"integrity": "sha512-uWcqAotbwDEU/9+Dm9e1/clO7hTB2kQ/94JYcGouBVLjoKmTeJTUPQKcJGpPwUjZcSqgYicbFqQSoJIW0yrFvg==",
"requires": {
"apollo-link": "^1.2.14",
"apollo-link-http-common": "^0.2.16",
"tslib": "^1.9.3"
}
},
"apollo-link-http-common": {
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz",
"integrity": "sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==",
"requires": {
"apollo-link": "^1.2.14",
"ts-invariant": "^0.4.0",
"tslib": "^1.9.3"
}
},
"apollo-link-ws": {
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/apollo-link-ws/-/apollo-link-ws-1.0.20.tgz",
"integrity": "sha512-mjSFPlQxmoLArpHBeUb2Xj+2HDYeTaJqFGOqQ+I8NVJxgL9lJe84PDWcPah/yMLv3rB7QgBDSuZ0xoRFBPlySw==",
"requires": {
"apollo-link": "^1.2.14",
"tslib": "^1.9.3"
}
},
"apollo-utilities": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz",
"integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==",
"requires": {
"@wry/equality": "^0.1.2",
"fast-json-stable-stringify": "^2.0.0",
"ts-invariant": "^0.4.0",
"tslib": "^1.10.0"
}
},
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
@ -1875,8 +1983,7 @@
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"dev": true
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"asynckit": {
"version": "0.4.0",
@ -2724,6 +2831,11 @@
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
"dev": true
},
"backo2": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -5029,8 +5141,7 @@
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"fastparse": {
"version": "1.1.2",
@ -5499,11 +5610,21 @@
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
"graphql": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-15.3.0.tgz",
"integrity": "sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w=="
},
"graphql-request": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-2.0.0.tgz",
"integrity": "sha512-Ww3Ax+G3l2d+mPT8w7HC9LfrKjutnCKtnDq7ZZp2ghVk5IQDjwAk3/arRF1ix17Ky15rm0hrSKVKxRhIVlSuoQ=="
},
"graphql-tag": {
"version": "2.10.4",
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.4.tgz",
"integrity": "sha512-O7vG5BT3w6Sotc26ybcvLKNTdfr4GfsIVMD+LdYqXCeJIYPRyp8BIsDOUtxw7S1PYvRw5vH3278J2EDezR6mfA=="
},
"handle-thing": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@ -6308,6 +6429,11 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true
},
"iterall": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz",
"integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg=="
},
"js-base64": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
@ -7340,6 +7466,14 @@
"is-wsl": "^1.1.0"
}
},
"optimism": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/optimism/-/optimism-0.10.3.tgz",
"integrity": "sha512-9A5pqGoQk49H6Vhjb9kPgAeeECfUDF6aIICbMDL23kDLStBn1MWk3YvcZ4xWF9CsSf6XEgvRLkXy4xof/56vVw==",
"requires": {
"@wry/context": "^0.4.0"
}
},
"original": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
@ -9420,6 +9554,33 @@
"resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
"integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
},
"subscriptions-transport-ws": {
"version": "0.9.17",
"resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.17.tgz",
"integrity": "sha512-hNHi2N80PBz4T0V0QhnnsMGvG3XDFDS9mS6BhZ3R12T6EBywC8d/uJscsga0cVO4DKtXCkCRrWm2sOYrbOdhEA==",
"requires": {
"backo2": "^1.0.2",
"eventemitter3": "^3.1.0",
"iterall": "^1.2.1",
"symbol-observable": "^1.0.4",
"ws": "^5.2.0"
},
"dependencies": {
"eventemitter3": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
},
"ws": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
"integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
"requires": {
"async-limiter": "~1.0.0"
}
}
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -9658,6 +9819,14 @@
"glob": "^7.1.2"
}
},
"ts-invariant": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz",
"integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==",
"requires": {
"tslib": "^1.9.3"
}
},
"ts-loader": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz",
@ -9725,8 +9894,7 @@
"tslib": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
"dev": true
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
},
"tty-browserify": {
"version": "0.0.0",
@ -10833,6 +11001,20 @@
"dev": true
}
}
},
"zen-observable": {
"version": "0.8.15",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
"integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ=="
},
"zen-observable-ts": {
"version": "0.8.21",
"resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz",
"integrity": "sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==",
"requires": {
"tslib": "^1.9.3",
"zen-observable": "^0.8.0"
}
}
}
}

View File

@ -52,9 +52,17 @@
},
"dependencies": {
"@types/qs": "^6.9.3",
"apollo-cache-inmemory": "^1.6.6",
"apollo-client": "^2.6.10",
"apollo-link": "^1.2.14",
"apollo-link-http": "^1.5.17",
"apollo-link-ws": "^1.0.20",
"apollo-utilities": "^1.3.4",
"bulma": "^0.7.2",
"bulma-switch": "^2.0.0",
"graphql": "^15.3.0",
"graphql-request": "^2.0.0",
"graphql-tag": "^2.10.4",
"jwt-decode": "^2.2.0",
"qs": "^6.9.4",
"react": "^16.12.0",
@ -65,6 +73,7 @@
"redux": "^4.0.4",
"redux-saga": "^1.1.3",
"styled-components": "^4.4.1",
"subscriptions-transport-ws": "^0.9.17",
"typescript": "^3.8.3"
}
}

View File

@ -14,8 +14,8 @@ export function HomePage() {
<div className="column is-4 is-offset-4">
<div className="box">
{
currentUser && currentUser.full_name ?
<p>Bonjour <span className="has-text-weight-bold">{currentUser.full_name}</span> !</p> :
currentUser && currentUser.email ?
<p>Bonjour <span className="has-text-weight-bold">{currentUser.email}</span> !</p> :
<p>Veuillez vous authentifier.</p>
}
</div>

View File

@ -2,6 +2,7 @@ export const Config = {
loginURL: get<string>("loginURL", "http://localhost:8081/login"),
logoutURL: get<string>("logoutURL", "http://localhost:8081/logout"),
graphQLEndpoint: get<string>("graphQLEndpoint", "http://localhost:8081/api/v1/graphql"),
subscriptionEndpoint: get<string>("subscriptionEndpoint", "ws://localhost:8081/api/v1/graphql"),
};
function get<T>(key: string, defaultValue: T):T {

View File

@ -39,7 +39,9 @@ function handleFetchProfileSuccess(state: AuthState, { profile }: fetchProfileSu
...state,
isAuthenticated: true,
currentUser: {
...profile,
email: profile.email,
connectedAt: profile.connectedAt,
createdAt: profile.createdAt,
}
};
};

View File

@ -1,7 +1,12 @@
import { all, put } from "redux-saga/effects";
import { fetchProfile } from "../actions/profile";
export function* initRootSaga() {
yield all([
fetchUserProfileSaga(),
]);
}
export function* fetchUserProfileSaga() {
yield put(fetchProfile());
}

View File

@ -7,5 +7,6 @@ export function* rootSaga() {
yield all([
initRootSaga(),
failureRootSaga(),
usersRootSaga(),
]);
}

View File

@ -1,4 +1,4 @@
import { DaddyClient } from "../../util/daddy";
import { DaddyClient, getClient } from "../../util/daddy";
import { Config } from "../../config";
import { all, takeLatest, put, select } from "redux-saga/effects";
import { FETCH_PROFILE_REQUEST, fetchProfile, FETCH_PROFILE_FAILURE, FETCH_PROFILE_SUCCESS } from "../actions/profile";
@ -18,12 +18,12 @@ export function* onCurrentUserChangeSaga() {
}
export function* fetchProfileSaga() {
const client = new DaddyClient(Config.graphQLEndpoint);
const client = getClient(Config.graphQLEndpoint, Config.subscriptionEndpoint);
let profile: User;
try {
const currentUser: User = yield select((state: RootState) => state.auth.currentUser);
profile = yield client.fetchUser(currentUser.email).then(result => result.user);
profile = yield client.fetchProfile().then(result => result.userProfile);
console.log(profile);
} catch(err) {
yield put({ type: FETCH_PROFILE_FAILURE, err });
return;

View File

@ -1,6 +1,5 @@
export interface User {
email: string
full_name?: string
updated_at?: Date
created_at?: Date
connectedAt?: Date
createdAt?: Date
}

View File

@ -1,5 +1,10 @@
import { GraphQLClient } from 'graphql-request'
import { Config } from "../config";
import ApolloClient from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { split } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import gql from 'graphql-tag';
export class UnauthorizedError extends Error {
constructor(...args: any[]) {
@ -8,30 +13,65 @@ export class UnauthorizedError extends Error {
}
}
let client: DaddyClient
export function getClient(graphQLEndpoint: string, subscriptionEndpoint: string): DaddyClient {
if (!client) {
client = new DaddyClient(graphQLEndpoint, subscriptionEndpoint);
}
return client;
}
export class DaddyClient {
gql: GraphQLClient
gql: ApolloClient<InMemoryCache>
constructor(endpoint: string) {
this.gql = new GraphQLClient(endpoint, {
headers: {
mode: 'cors',
constructor(graphQLEndpoint: string, subscriptionEndpoint: string) {
const wsLink = new WebSocketLink({
uri: subscriptionEndpoint,
options: {
reconnect: true
}
});
const httpLink = new HttpLink({
uri: graphQLEndpoint,
fetchOptions: {
mode: 'cors',
credentials: 'include',
}
});
const link = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
);
this.gql = new ApolloClient<any>({
link: link,
cache: new InMemoryCache(),
});
}
fetchUser(email: string) {
return this.gql.rawRequest(`
query fetchUser {
user(where: {email: {eq: $email}}) {
id
created_at
updated_at
fetchProfile() {
return this.gql.query({
query: gql`
query {
userProfile {
email,
full_name
createdAt,
connectedAt
}
}
`, { email })
}`
})
.then(this.assertAuthorization)
}

2
go.mod
View File

@ -9,9 +9,11 @@ require (
github.com/cortesi/modd v0.0.0-20200630120222-8983974e5450 // indirect
github.com/go-chi/chi v4.1.0+incompatible
github.com/gorilla/sessions v1.2.0
github.com/gorilla/websocket v1.2.0
github.com/jackc/pgx v3.6.2+incompatible
github.com/jackc/pgx/v4 v4.7.1
github.com/pkg/errors v0.9.1
github.com/rs/cors v1.7.0
github.com/vektah/gqlparser/v2 v2.0.1
gitlab.com/wpetit/goweb v0.0.0-20200707070104-985ce3eba3c2
gopkg.in/yaml.v2 v2.2.8

2
go.sum
View File

@ -248,6 +248,8 @@ github.com/rjeczalik/notify v0.0.0-20181126183243-629144ba06a1 h1:FLWDC+iIP9BWgY
github.com/rjeczalik/notify v0.0.0-20181126183243-629144ba06a1/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=

View File

@ -37,13 +37,19 @@ func NewFromFile(filepath string) (*Config, error) {
}
type HTTPConfig struct {
Address string `yaml:"address" env:"HTTP_ADDRESS"`
CookieAuthenticationKey string `yaml:"cookieAuthenticationKey" env:"HTTP_COOKIE_AUTHENTICATION_KEY"`
CookieEncryptionKey string `yaml:"cookieEncryptionKey" env:"HTTP_COOKIE_ENCRYPTION_KEY"`
CookieMaxAge int `yaml:"cookieMaxAge" env:"HTTP_COOKIE_MAX_AGE"`
TemplateDir string `yaml:"templateDir" env:"HTTP_TEMPLATE_DIR"`
PublicDir string `yaml:"publicDir" env:"HTTP_PUBLIC_DIR"`
FrontendURL string `yaml:"frontendURL" env:"HTTP_FRONTEND_URL"`
Address string `yaml:"address" env:"HTTP_ADDRESS"`
CookieAuthenticationKey string `yaml:"cookieAuthenticationKey" env:"HTTP_COOKIE_AUTHENTICATION_KEY"`
CookieEncryptionKey string `yaml:"cookieEncryptionKey" env:"HTTP_COOKIE_ENCRYPTION_KEY"`
CookieMaxAge int `yaml:"cookieMaxAge" env:"HTTP_COOKIE_MAX_AGE"`
TemplateDir string `yaml:"templateDir" env:"HTTP_TEMPLATE_DIR"`
PublicDir string `yaml:"publicDir" env:"HTTP_PUBLIC_DIR"`
FrontendURL string `yaml:"frontendURL" env:"HTTP_FRONTEND_URL"`
CORS CORSConfig `yaml:"cors"`
}
type CORSConfig struct {
AllowedOrigins []string `yaml:"allowedOrigins" env:"HTTP_CORS_ALLOWED_ORIGINS"`
AllowCredentials bool `yaml:"allowCredentials" env:"HTTP_CORS_ALLOW_CREDENTIALS"`
}
type OIDCConfig struct {
@ -83,6 +89,10 @@ func NewDefault() *Config {
TemplateDir: "template",
PublicDir: "public",
FrontendURL: "http://localhost:8080",
CORS: CORSConfig{
AllowedOrigins: []string{"http://localhost:8080"},
AllowCredentials: true,
},
},
OIDC: OIDCConfig{
IssuerURL: "http://localhost:4444/",

View File

@ -3,6 +3,9 @@ package route
import (
"net/http"
"forge.cadoles.com/Cadoles/daddy/internal/session"
"github.com/pkg/errors"
"forge.cadoles.com/Cadoles/daddy/internal/config"
oidc "forge.cadoles.com/wpetit/goweb-oidc"
"gitlab.com/wpetit/goweb/logger"
@ -21,6 +24,10 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
logger.F("postLogoutURL", conf.OIDC.PostLogoutRedirectURL),
)
if err := session.ClearUserEmail(w, r, false); err != nil {
panic(errors.WithStack(err))
}
client.Logout(w, r, conf.OIDC.PostLogoutRedirectURL)
}

View File

@ -1,15 +1,22 @@
package route
import (
"net/http"
"time"
"forge.cadoles.com/Cadoles/daddy/internal/config"
"forge.cadoles.com/Cadoles/daddy/internal/graph"
"forge.cadoles.com/Cadoles/daddy/internal/graph/generated"
"forge.cadoles.com/Cadoles/daddy/internal/session"
oidc "forge.cadoles.com/wpetit/goweb-oidc"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/gorilla/websocket"
"github.com/go-chi/chi"
"github.com/rs/cors"
"gitlab.com/wpetit/goweb/static"
)
@ -21,20 +28,39 @@ func Mount(r *chi.Mux, config *config.Config) error {
r.Get("/logout/redirect", handleLogoutRedirect)
r.Route("/api", func(r chi.Router) {
r.Use(cors.New(cors.Options{
AllowedOrigins: config.HTTP.CORS.AllowedOrigins,
AllowCredentials: config.HTTP.CORS.AllowCredentials,
Debug: config.Debug,
}).Handler)
r.Use(oidc.Middleware)
r.Use(session.UserEmailMiddleware)
gql := handler.NewDefaultServer(
gql := handler.New(
generated.NewExecutableSchema(generated.Config{
Resolvers: &graph.Resolver{},
}),
)
gql.AddTransport(transport.POST{})
gql.AddTransport(&transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
Upgrader: websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
// TODO Check WS connection origin
return true
},
ReadBufferSize: 1024,
WriteBufferSize: 1024,
},
})
if config.Debug {
r.Get("/v1/graphql", playground.Handler("GraphQL playground", "/api/v1/graphql"))
gql.Use(extension.Introspection{})
r.Get("/v1/playground", playground.Handler("GraphQL playground", "/api/v1/graphql"))
}
r.Post("/v1/graphql", gql.ServeHTTP)
r.Handle("/v1/graphql", gql)
})
notFoundHandler := r.NotFoundHandler()

View File

@ -61,6 +61,23 @@ func SaveUserEmail(w http.ResponseWriter, r *http.Request, email string) error {
return nil
}
func ClearUserEmail(w http.ResponseWriter, r *http.Request, saveSession bool) error {
sess, err := getSession(w, r)
if err != nil {
return errors.WithStack(err)
}
sess.Unset(string(userEmailKey))
if saveSession {
if err := sess.Save(w, r); err != nil {
return errors.WithStack(err)
}
}
return nil
}
func GetUserEmail(w http.ResponseWriter, r *http.Request) (string, error) {
sess, err := getSession(w, r)
if err != nil {