Skip to content

Commit 459dcbf

Browse files
authored
Merge pull request #93 from hwgilbert16/develop
v1.1.0 Release
2 parents d3ae25d + 0769606 commit 459dcbf

File tree

89 files changed

+3857
-2136
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+3857
-2136
lines changed

.github/workflows/docker.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: Build and push image
22
on:
33
push:
4-
branches: [release]
4+
tags:
5+
- '*'
56

67
jobs:
78
build:
@@ -37,6 +38,6 @@ jobs:
3738
context: .
3839
file: ./Dockerfile
3940
push: true
40-
tags: ${{ secrets.DOCKER_USERNAME }}/scholarsome:latest
41+
tags: ${{ secrets.DOCKER_USERNAME }}/scholarsome:latest,${{ secrets.DOCKER_USERNAME }}/scholarsome:${{ github.ref_name }}
4142

4243

README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ https://scholarsome.com
2424
</p>
2525

2626
<p align="center">
27-
<img src="https://i.imgur.com/MshTOaL.png">
27+
<img src="apps/docs/static/img/homepage.png">
2828
</p>
2929

3030
## About
@@ -37,17 +37,17 @@ You can read more about our design philosophy <a href="https://github.com/hwgilb
3737

3838
## Features
3939

40-
Implemented features include:
41-
42-
- Create your own study sets ✅
43-
- Import sets from Anki and Quizlet ✅
44-
- Study flashcards in multiple learning modes
45-
- Create quizzes using fill-in-the-blank, true/false, and multiple choice questions
46-
- Edit your sets
47-
- Change set visibility
48-
49-
<img src="https://i.imgur.com/Xey0pzK.gif" width="50%">
50-
<img src="https://s12.gifyu.com/images/SWNMa.gif" width="50%">
40+
- Create your own study sets 🏗️
41+
- Share your sets with other users 🤝
42+
- Import sets from Anki, Quizlet, and CSV files 🔼
43+
- Export sets to Anki, Quizlet, and CSV files 🔽
44+
- Study flashcards in multiple learning modes, mimicking real-world flashcards 📖
45+
- Create quizzes using fill-in-the-blank, true/false, and multiple choice questions ✏️
46+
- Edit your sets 🛠️
47+
- Change set visibility 🔓
48+
49+
<img src="https://s13.gifyu.com/images/S0cB1.gif" width="50%">
50+
<img src="https://s13.gifyu.com/images/S0cBD.gif" width="50%">
5151

5252
## Features coming soon...
5353

apps/api/src/app/app.module.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import { CardsModule } from "./cards/cards.module";
1616
import { UsersModule } from "./users/users.module";
1717
import { RedisModule } from "@liaoliaots/nestjs-redis";
1818
import { JwtModule } from "@nestjs/jwt";
19-
import { APP_INTERCEPTOR } from "@nestjs/core";
20-
import { GlobalInterceptor } from "./auth/global.interceptor";
2119
import { MediaModule } from "./media/media.module";
20+
import { TokenRefreshMiddleware } from "./providers/token-refresh.middleware";
21+
import { ConvertingModule } from "./converting/converting.module";
2222

2323
@Module({
2424
imports: [
@@ -68,15 +68,11 @@ import { MediaModule } from "./media/media.module";
6868
inject: [ConfigService]
6969
}),
7070
global: true
71-
}
71+
},
72+
ConvertingModule
7273
],
7374
controllers: [],
74-
providers: [
75-
{
76-
provide: APP_INTERCEPTOR,
77-
useClass: GlobalInterceptor
78-
}
79-
],
75+
providers: [],
8076
exports: [JwtModule]
8177
})
8278
export class AppModule implements NestModule {
@@ -92,5 +88,9 @@ export class AppModule implements NestModule {
9288
.apply(HttpsRedirectMiddleware)
9389
.forRoutes({ path: "*", method: RequestMethod.ALL });
9490
}
91+
92+
consumer
93+
.apply(TokenRefreshMiddleware)
94+
.forRoutes({ path: "*", method: RequestMethod.ALL });
9595
}
9696
}

apps/api/src/app/auth/auth.controller.spec.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Test } from "@nestjs/testing";
77
import { ConfigService } from "@nestjs/config";
88
import { UsersService } from "../users/users.service";
99
import { RedisService } from "@liaoliaots/nestjs-redis";
10-
import { ThrottlerGuard, ThrottlerModule } from "@nestjs/throttler";
10+
import { ThrottlerModule } from "@nestjs/throttler";
1111
import { MailService } from "../providers/mail/mail.service";
1212
import { Request, Response } from "express";
1313
import { HttpException } from "@nestjs/common";
@@ -123,8 +123,7 @@ describe("AuthController", () => {
123123
{
124124
provide: RedisService,
125125
useValue: createMock<RedisService>()
126-
},
127-
ThrottlerGuard
126+
}
128127
],
129128
controllers: [
130129
AuthController

apps/api/src/app/auth/auth.controller.ts

+7-16
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
import { UsersService } from "../users/users.service";
1616
import { AuthService } from "./auth.service";
1717
import { Response, Request as ExpressRequest } from "express";
18-
import { Throttle, ThrottlerGuard } from "@nestjs/throttler";
1918
import { ApiResponse, ApiResponseOptions } from "@scholarsome/shared";
2019
import { LoginDto } from "./dto/login.dto";
2120
import { RegisterDto } from "./dto/register.dto";
@@ -24,32 +23,24 @@ import * as jwt from "jsonwebtoken";
2423
import { ConfigService } from "@nestjs/config";
2524
import * as bcrypt from "bcrypt";
2625
import { MailService } from "../providers/mail/mail.service";
27-
import { RedisService } from "@liaoliaots/nestjs-redis";
28-
import Redis from "ioredis";
29-
import { JwtService } from "@nestjs/jwt";
3026
import { User } from "@prisma/client";
3127
import { ApiExcludeController, ApiTags } from "@nestjs/swagger";
28+
import { Throttle, ThrottlerGuard } from "@nestjs/throttler";
3229

3330
@ApiTags("Authentication")
3431
@ApiExcludeController()
3532
@UseGuards(ThrottlerGuard)
3633
@Controller("auth")
3734
export class AuthController {
38-
private readonly redis: Redis;
39-
4035
/**
4136
* @ignore
4237
*/
4338
constructor(
4439
private readonly usersService: UsersService,
4540
private readonly authService: AuthService,
4641
private readonly configService: ConfigService,
47-
private readonly mailService: MailService,
48-
private readonly jwtService: JwtService,
49-
private readonly redisService: RedisService
50-
) {
51-
this.redis = this.redisService.getClient();
52-
}
42+
private readonly mailService: MailService
43+
) {}
5344

5445
/*
5546
* Password reset routes
@@ -145,10 +136,10 @@ export class AuthController {
145136
/**
146137
* Sends a password reset for a given user
147138
*
148-
* @remarks Throttled to 1 request per minute
139+
* @remarks Throttled to 1 request per 5 seconds
149140
* @returns Success response
150141
*/
151-
@Throttle(5, 60000)
142+
@Throttle(1, 5)
152143
@Get("reset/sendReset/:email")
153144
async sendReset(
154145
@Param() params: { email: string }
@@ -262,10 +253,10 @@ export class AuthController {
262253
/**
263254
* Registers a new user
264255
*
265-
* @remarks Throttled to 1 request per 3 minutes
256+
* @remarks Throttled to 1 request per 5 seconds
266257
* @returns Success response
267258
*/
268-
@Throttle(5, 180000)
259+
@Throttle(1, 5)
269260
@Post("register")
270261
async register(
271262
@Body() registerDto: RegisterDto,

apps/api/src/app/cards/dto/createCard.dto.ts

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { IsNotEmpty, IsNumber, IsString } from "class-validator";
22
import { ApiProperty } from "@nestjs/swagger";
3+
import { Transform, TransformFnParams } from "class-transformer";
4+
import * as sanitizeHtml from "sanitize-html";
35

46
export class CreateCardDto {
57
@ApiProperty({
@@ -24,6 +26,11 @@ export class CreateCardDto {
2426
})
2527
@IsString()
2628
@IsNotEmpty()
29+
@Transform((params: TransformFnParams) => sanitizeHtml(params.value, {
30+
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
31+
allowedAttributes: { "img": ["src", "width", "height"], "span": ["style"] },
32+
allowedSchemes: ["data"]
33+
}))
2734
term: string;
2835

2936
@ApiProperty({
@@ -32,5 +39,10 @@ export class CreateCardDto {
3239
})
3340
@IsString()
3441
@IsNotEmpty()
42+
@Transform((params: TransformFnParams) => sanitizeHtml(params.value, {
43+
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
44+
allowedAttributes: { "img": ["src", "width", "height"], "span": ["style"] },
45+
allowedSchemes: ["data"]
46+
}))
3547
definition: string;
3648
}

apps/api/src/app/cards/dto/updateCard.dto.ts

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { IsNotEmpty, IsNumber, IsOptional, IsString } from "class-validator";
22
import { ApiProperty } from "@nestjs/swagger";
3+
import { Transform, TransformFnParams } from "class-transformer";
4+
import * as sanitizeHtml from "sanitize-html";
35

46
export class UpdateCardDto {
57
@ApiProperty({
@@ -18,6 +20,11 @@ export class UpdateCardDto {
1820
@IsString()
1921
@IsOptional()
2022
@IsNotEmpty()
23+
@Transform((params: TransformFnParams) => sanitizeHtml(params.value, {
24+
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
25+
allowedAttributes: { "img": ["src", "width", "height"], "span": ["style"] },
26+
allowedSchemes: ["data"]
27+
}))
2128
term?: string;
2229

2330
@ApiProperty({
@@ -27,5 +34,10 @@ export class UpdateCardDto {
2734
@IsString()
2835
@IsOptional()
2936
@IsNotEmpty()
37+
@Transform((params: TransformFnParams) => sanitizeHtml(params.value, {
38+
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
39+
allowedAttributes: { "img": ["src", "width", "height"], "span": ["style"] },
40+
allowedSchemes: ["data"]
41+
}))
3042
definition?: string;
3143
}

0 commit comments

Comments
 (0)