diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
index cc3da93..41f1055 100644
--- a/.idea/jsLibraryMappings.xml
+++ b/.idea/jsLibraryMappings.xml
@@ -2,5 +2,6 @@
+
\ No newline at end of file
diff --git a/backend/package-lock.json b/backend/package-lock.json
index f25c481..ed70959 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -427,6 +427,11 @@
"integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
"dev": true
},
+ "@types/url-join": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.0.tgz",
+ "integrity": "sha512-awrJu8yML4E/xTwr2EMatC+HBnHGoDxc2+ImA9QyeUELI1S7dOCIZcyjki1rkwoA8P2D2NVgLAJLjnclkdLtAw=="
+ },
"@types/ws": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz",
@@ -2076,11 +2081,41 @@
"resolved": "https://registry.npmjs.org/fastify-error/-/fastify-error-0.3.0.tgz",
"integrity": "sha512-Jm2LMTB5rsJqlS1+cmgqqM9tTs0UrlgYR7TvDT3ZgXsUI5ib1NjQlqZHf+tDK5tVPdFGwyq02wAoJtyYIRSiFA=="
},
+ "fastify-http-proxy": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/fastify-http-proxy/-/fastify-http-proxy-4.2.0.tgz",
+ "integrity": "sha512-qxIj5AHrt4sgTVggv1km+dr1105gzHRk39/rhzuNIUy747m2WswsLM+ZeedulK/EGYSTNluKwNhbqwPSZ4JvnA==",
+ "requires": {
+ "fastify-reply-from": "^3.1.3",
+ "ws": "^7.4.1"
+ },
+ "dependencies": {
+ "ws": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
+ "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
+ }
+ }
+ },
"fastify-plugin": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.0.tgz",
"integrity": "sha512-ZdCvKEEd92DNLps5n0v231Bha8bkz1DjnPP/aEz37rz/q42Z5JVLmgnqR4DYuNn3NXAO3IDCPyRvgvxtJ4Ym4w=="
},
+ "fastify-reply-from": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/fastify-reply-from/-/fastify-reply-from-3.5.0.tgz",
+ "integrity": "sha512-kNc0taosEyZz1DZBo/Dt4ihxF210gqalhRAiKFKT0VvGCL/+3A1JunlY/ExeoJUyfiCUWpRJ87pj4FCdrhbZLA==",
+ "requires": {
+ "end-of-stream": "^1.4.1",
+ "fastify-plugin": "^3.0.0",
+ "http-errors": "^1.8.0",
+ "pump": "^3.0.0",
+ "semver": "^7.2.1",
+ "tiny-lru": "^7.0.0",
+ "undici": "^2.1.0"
+ }
+ },
"fastify-sensible": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fastify-sensible/-/fastify-sensible-3.1.0.tgz",
@@ -4118,6 +4153,11 @@
"random-bytes": "~1.0.0"
}
},
+ "undici": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-2.2.1.tgz",
+ "integrity": "sha512-21sJmMvJOMsyt/2pQPgB5Ruvm2ADTTm34NHRy4kzfeW9uMO7gK2oN0f+5KaJCmoKGJb8KxdU6yWpW0SphFHadw=="
+ },
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@@ -4131,6 +4171,11 @@
"punycode": "^2.1.0"
}
},
+ "url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/backend/package.json b/backend/package.json
index b0cfc3f..c92dc4e 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -17,11 +17,13 @@
"@types/express": "^4.17.10",
"@types/lodash": "^4.14.167",
"@types/node": "^14.14.21",
+ "@types/url-join": "^4.0.0",
"@wulkanowy/sdk": "^0.1.1",
"apollo-server-fastify": "^2.19.2",
"dotenv": "^8.2.0",
"fastify": "^3.10.1",
"fastify-cookie": "^5.1.0",
+ "fastify-http-proxy": "^4.2.0",
"fastify-sensible": "^3.1.0",
"fastify-session": "^5.2.1",
"lodash": "^4.17.20",
@@ -32,7 +34,8 @@
"ts-node": "^9.1.1",
"type-graphql": "^1.1.1",
"typeorm": "^0.2.30",
- "typescript": "^4.1.3"
+ "typescript": "^4.1.3",
+ "url-join": "^4.0.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.13.0",
diff --git a/backend/src/constants.ts b/backend/src/constants.ts
index 53f3521..96e9079 100644
--- a/backend/src/constants.ts
+++ b/backend/src/constants.ts
@@ -4,3 +4,5 @@ export const scopes = [
'notes',
'achievements',
];
+
+export const websitePrefix = '/';
diff --git a/backend/src/index.ts b/backend/src/index.ts
index 4828588..dec51d2 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -5,8 +5,10 @@ dotenv.config();
import Fastify from 'fastify';
import FastifyCookie from 'fastify-cookie';
+import FastifyHttpProxy from 'fastify-http-proxy';
import FastifySensible from 'fastify-sensible';
import FastifySession from 'fastify-session';
+import { websitePrefix } from './constants';
import database from './database/database';
import registerOAuth from './routes/oauth2';
import registerWebsiteApi from './routes/website-api';
@@ -28,6 +30,15 @@ async function start() {
secure: false, // TODO: Remove this line or add development env variable
},
});
+
+ const websiteProxyUpstream = process.env.PROXY_WEBSITE;
+ if (websiteProxyUpstream !== undefined) {
+ await server.register(FastifyHttpProxy, {
+ upstream: websiteProxyUpstream,
+ prefix: websitePrefix,
+ });
+ }
+
await server.register(registerOAuth, { prefix: '/api/oauth', logLevel: 'info' });
await server.register(registerWebsiteApi, { prefix: '/api/website', logLevel: 'info' });
diff --git a/backend/src/routes/oauth2/authorize.ts b/backend/src/routes/oauth2/authorize.ts
index d043bdd..e05ed80 100644
--- a/backend/src/routes/oauth2/authorize.ts
+++ b/backend/src/routes/oauth2/authorize.ts
@@ -1,6 +1,7 @@
import _ from 'lodash';
import { nanoid } from 'nanoid';
-import { scopes } from '../../constants';
+import urlJoin from 'url-join';
+import { scopes, websitePrefix } from '../../constants';
import database from '../../database/database';
import { ParamError, ScopeError } from '../../errors';
import type { MyFastifyInstance, StudentsMode } from '../../types';
@@ -10,7 +11,7 @@ import {
} from '../../utils';
export default function registerAuthorize(server: MyFastifyInstance): void {
- server.post('/authorize', async (
+ server.get('/authorize', async (
request,
reply,
) => {
@@ -80,7 +81,7 @@ export default function registerAuthorize(server: MyFastifyInstance): void {
studentsMode,
});
- await reply.redirect(`/authenticate-prompt?prompt_id=${promptId}`);
+ await reply.redirect(urlJoin(websitePrefix, `/authenticate-prompt?prompt_id=${promptId}`));
return;
}
await reply.redirect(`${request.query.redirect_uri}?error=unsupported_response_type`);
diff --git a/backend/src/routes/website-api/index.ts b/backend/src/routes/website-api/index.ts
index f890b30..5bd7a95 100644
--- a/backend/src/routes/website-api/index.ts
+++ b/backend/src/routes/website-api/index.ts
@@ -1,7 +1,8 @@
import { ApolloServer } from 'apollo-server-fastify';
import { buildSchema } from 'type-graphql';
+import { ParamError } from '../../errors';
import type { ApolloContext, MyFastifyInstance } from '../../types';
-import { getSessionData } from '../../utils';
+import { getSessionData, isObject, validateParam } from '../../utils';
import LoginResolver from './resolvers/login-resolver';
import PromptInfoResolver from './resolvers/prompt-info-resolver';
import type { WebsiteAPIContext } from './types';
@@ -26,5 +27,26 @@ export default async function registerWebsiteApi(server: MyFastifyInstance): Pro
origin: false,
},
}));
- console.log(apolloServer.graphqlPath);
+
+ server.get('/deny', async (
+ request,
+ reply,
+ ) => {
+ if (!isObject(request.query)) {
+ server.log.warn('Request query is not an object');
+ throw server.httpErrors.badRequest();
+ }
+ try {
+ validateParam('prompt_id', request.query.prompt_id);
+ } catch (error) {
+ if (error instanceof ParamError) {
+ throw server.httpErrors.badRequest(error.message);
+ }
+ server.log.error(error);
+ throw server.httpErrors.internalServerError();
+ }
+ const prompt = getSessionData(request.session).prompts.get(request.query.prompt_id);
+ if (!prompt) throw server.httpErrors.badRequest('Prompt data not found');
+ await reply.redirect(`${prompt.redirectUri}?error=access_denied&error_description=${encodeURIComponent('User denied')}`);
+ });
}
diff --git a/website/src/pages/authenticate-prompt/app.vue b/website/src/pages/authenticate-prompt/app.vue
index aa82a2f..cf79c4b 100644
--- a/website/src/pages/authenticate-prompt/app.vue
+++ b/website/src/pages/authenticate-prompt/app.vue
@@ -7,7 +7,10 @@
-
+
+ Brak wymaganego parametru prompt_id
+
+
Nie udało się wczytać danych
@@ -97,7 +100,7 @@
-
+
Odmów
@@ -165,6 +168,8 @@ export interface PromptInfo {
export default class AuthenticatePromptApp extends Vue {
promptInfo: PromptInfo | null = null;
+ promptId: string | null = null;
+
promptInfoError = false;
step = 1;
@@ -201,6 +206,11 @@ export default class AuthenticatePromptApp extends Vue {
}));
}
+ get denyUrl() {
+ if (!this.promptId) return undefined;
+ return `/api/website/deny?prompt_id=${this.promptId}`;
+ }
+
async loadPromptInfo() {
this.promptInfoError = false;
this.promptInfo = null;
@@ -222,6 +232,9 @@ export default class AuthenticatePromptApp extends Vue {
}
async created() {
+ const searchParams = new URLSearchParams(window.location.search);
+ this.promptId = searchParams.get('prompt_id');
+ if (!this.promptId) return;
await this.loadPromptInfo();
}
}
diff --git a/website/website.iml b/website/website.iml
index 8021953..652a0e7 100644
--- a/website/website.iml
+++ b/website/website.iml
@@ -5,5 +5,6 @@
+
\ No newline at end of file