Working sessions
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
PORT=3000
|
PORT=3000
|
||||||
MONGODB_URI=
|
MONGODB_URI=
|
||||||
|
SECRET=
|
||||||
9
backend/scripts.json
Normal file
9
backend/scripts.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"dev": {
|
||||||
|
"cmd": "./src/index.ts",
|
||||||
|
"desc": "Run the development server.",
|
||||||
|
"allow": ["net", "env", "read"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
export default async function getUserId(token: string, authProvider: string) {
|
export default async function getProviderId(token: string, authProvider: string) {
|
||||||
switch (authProvider) {
|
switch (authProvider) {
|
||||||
case 'yandex':
|
case 'yandex':
|
||||||
return getYandexUserId(token);
|
return getYandexId(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getYandexUserId(token: string) {
|
async function getYandexId(token: string) {
|
||||||
const baseUrl = 'https://login.yandex.ru/info';
|
const baseUrl = 'https://login.yandex.ru/info';
|
||||||
const response = await fetch(baseUrl, {
|
const response = await fetch(baseUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1,10 +1,18 @@
|
|||||||
import { config } from "https://deno.land/x/dotenv@v3.2.0/mod.ts";
|
import "https://deno.land/x/dotenv@v3.2.0/load.ts";
|
||||||
import { Application } from "https://deno.land/x/oak@v10.5.1/mod.ts";
|
import { Application } from "https://deno.land/x/oak@v10.5.1/mod.ts";
|
||||||
|
import { Session, CookieStore } from "https://deno.land/x/oak_sessions@v3.4.0/mod.ts";
|
||||||
import { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
|
import { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
|
||||||
|
|
||||||
import routes from './routes.ts'
|
import routes from './routes/index.ts'
|
||||||
|
|
||||||
|
const PORT = Number(Deno.env.get('PORT'));
|
||||||
|
const SECRET = Deno.env.get('SECRET');
|
||||||
|
|
||||||
const app = new Application();
|
const app = new Application();
|
||||||
|
const store = new CookieStore(SECRET);
|
||||||
|
const session = new Session(store);
|
||||||
|
|
||||||
|
app.use(session.initMiddleware());
|
||||||
app.use(oakCors({
|
app.use(oakCors({
|
||||||
origin: 'http://localhost:8080',
|
origin: 'http://localhost:8080',
|
||||||
credentials: true
|
credentials: true
|
||||||
@@ -12,5 +20,5 @@ app.use(oakCors({
|
|||||||
app.use(routes.routes());
|
app.use(routes.routes());
|
||||||
app.use(routes.allowedMethods());
|
app.use(routes.allowedMethods());
|
||||||
|
|
||||||
console.log(`👂 on port ${Number(config().PORT)}`);
|
console.log(`👂 on port ${PORT}`);
|
||||||
await app.listen({ port: Number(config().PORT) });
|
await app.listen({ port: PORT });
|
||||||
|
|||||||
31
backend/src/models/Session.ts
Normal file
31
backend/src/models/Session.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
export default class Session {
|
||||||
|
userId: string;
|
||||||
|
token: string;
|
||||||
|
expireAt: Date;
|
||||||
|
lifetime = 30 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
userId,
|
||||||
|
token,
|
||||||
|
expireAt
|
||||||
|
}: {
|
||||||
|
userId: string,
|
||||||
|
token?: string,
|
||||||
|
expireAt?: Date
|
||||||
|
}) {
|
||||||
|
const nowDate = new Date();
|
||||||
|
|
||||||
|
this.userId = userId;
|
||||||
|
this.token = token ?? crypto.randomUUID();
|
||||||
|
this.expireAt = expireAt ?? new Date(nowDate.getTime() + this.lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
extend() {
|
||||||
|
const nowDate = new Date();
|
||||||
|
this.expireAt = new Date(nowDate.getTime() + this.lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
revoke() {
|
||||||
|
this.expireAt = new Date();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,23 @@
|
|||||||
import Task from './Task.ts';
|
import Task from './Task.ts';
|
||||||
|
|
||||||
export default class User {
|
export default class User {
|
||||||
userId: string;
|
id: string;
|
||||||
|
providerId: string;
|
||||||
authProvider: string;
|
authProvider: string;
|
||||||
tasks: Array<Task>;
|
tasks: Array<Task>;
|
||||||
categories: Array<string>;
|
categories: Array<string>;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
userId,
|
providerId,
|
||||||
authProvider
|
authProvider
|
||||||
}: {
|
}: {
|
||||||
userId: string,
|
providerId: string,
|
||||||
authProvider: string
|
authProvider: string
|
||||||
}) {
|
}) {
|
||||||
this.userId = userId;
|
this.providerId = providerId;
|
||||||
this.authProvider = authProvider;
|
this.authProvider = authProvider;
|
||||||
|
this.id = `${providerId}@${authProvider}`;
|
||||||
this.tasks = [];
|
this.tasks = [];
|
||||||
this.categories = [];
|
this.categories = [];
|
||||||
this.updatedAt = new Date();
|
this.updatedAt = new Date();
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { config } from "https://deno.land/x/dotenv@v3.2.0/mod.ts";
|
import "https://deno.land/x/dotenv@v3.2.0/load.ts";
|
||||||
import { Router } from "https://deno.land/x/oak@v10.5.1/mod.ts";
|
import { Router } from "https://deno.land/x/oak@v10.5.1/mod.ts";
|
||||||
// import onyx from "https://deno.land/x/onyx@v1.0.1/mod.ts";
|
|
||||||
import { MongoClient } from "https://deno.land/x/mongo@v0.29.4/mod.ts";
|
import { MongoClient } from "https://deno.land/x/mongo@v0.29.4/mod.ts";
|
||||||
|
|
||||||
import User from './models/User.ts';
|
import User from '../models/User.ts';
|
||||||
import getUserId from './getUserId.ts';
|
import getProviderId from '../getProviderId.ts';
|
||||||
|
|
||||||
|
const MONGODB_URI = String(Deno.env.get('MONGODB_URI'));
|
||||||
|
|
||||||
const client = new MongoClient();
|
const client = new MongoClient();
|
||||||
await client.connect(config().MONGODB_URI);
|
await client.connect(MONGODB_URI);
|
||||||
|
|
||||||
const db = client.database("worktime");
|
const db = client.database("worktime");
|
||||||
const users = db.collection<User>("users");
|
const users = db.collection<User>("users");
|
||||||
@@ -18,18 +19,27 @@ const endpoints = new Router()
|
|||||||
const token = body.token;
|
const token = body.token;
|
||||||
const authProvider = body.authProvider;
|
const authProvider = body.authProvider;
|
||||||
|
|
||||||
const userId = await getUserId(token, authProvider);
|
const providerId = await getProviderId(token, authProvider);
|
||||||
|
|
||||||
await users.insertOne(new User({
|
let user = await users.findOne({
|
||||||
userId,
|
providerId,
|
||||||
authProvider
|
authProvider
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
user = new User({
|
||||||
|
providerId,
|
||||||
|
authProvider
|
||||||
|
});
|
||||||
|
await users.insertOne(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
await ctx.state.session.set('userId', user.id);
|
||||||
|
|
||||||
ctx.response.body = 'success';
|
ctx.response.body = 'success';
|
||||||
})
|
})
|
||||||
|
|
||||||
const routes = new Router()
|
const routes = new Router()
|
||||||
.use("/api", endpoints.routes(), endpoints.allowedMethods())
|
.use("/api", endpoints.routes(), endpoints.allowedMethods())
|
||||||
// .use(onyx.initialize())
|
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
16803
frontend/package-lock.json
generated
16803
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "worktime",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user