Skip to content

Commit

Permalink
quick save
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Jun 11, 2024
1 parent 341eb4e commit 6faa5d1
Show file tree
Hide file tree
Showing 35 changed files with 656 additions and 711 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VITE_API_BASE_URL=REPLACE_ME
VITE_API_BASE_URL=http://localhost:8000/
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"//": "🚫 Don't add `dependencies` below that are inherited from the CFL package.",
"dependencies": {
"codeforlife": "github:ocadotechnology/codeforlife-package-javascript#v2.0.0"
"codeforlife": "github:ocadotechnology/codeforlife-package-javascript#auth_flow"
},
"//": "✅ Do add `devDependencies` below that are `peerDependencies` in the CFL package.",
"devDependencies": {
Expand Down
Empty file modified scripts/run
100644 → 100755
Empty file.
39 changes: 0 additions & 39 deletions src/App.css

This file was deleted.

105 changes: 0 additions & 105 deletions src/App.test.tsx

This file was deleted.

72 changes: 10 additions & 62 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,15 @@
import "./App.css"
import { Counter } from "./features/counter/Counter"
import { Quotes } from "./features/quotes/Quotes"
import logo from "./logo.svg"
import { CssBaseline, ThemeProvider } from "@mui/material"
import type { FC } from "react"

const App = () => {
import theme from "./app/theme"
import Router from "./router"

const App: FC = () => {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<Counter />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<Quotes />
<span>
<span>Learn </span>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
React
</a>
<span>, </span>
<a
className="App-link"
href="https://redux.js.org"
target="_blank"
rel="noopener noreferrer"
>
Redux
</a>
<span>, </span>
<a
className="App-link"
href="https://redux-toolkit.js.org"
target="_blank"
rel="noopener noreferrer"
>
Redux Toolkit
</a>
<span>, </span>
<a
className="App-link"
href="https://react-redux.js.org"
target="_blank"
rel="noopener noreferrer"
>
React Redux
</a>
,<span> and </span>
<a
className="App-link"
href="https://reselect.js.org"
target="_blank"
rel="noopener noreferrer"
>
Reselect
</a>
</span>
</header>
</div>
<ThemeProvider theme={theme}>
<CssBaseline />
<Router />
</ThemeProvider>
)
}

Expand Down
73 changes: 73 additions & 0 deletions src/api/sso.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// TODO: rename this file to session.ts and move to codeforlife-sso-frontend.

import { type Class, type OtpBypassToken, type User } from "codeforlife/api"
import { type SessionMetadata } from "codeforlife/hooks"
import { type Arg } from "codeforlife/utils/api"

import api from "."

const baseUrl = "sso/session/"

const ssoApi = api.injectEndpoints({
endpoints: build => ({
loginWithEmail: build.mutation<
SessionMetadata,
Arg<User, "email" | "password">
>({
query: body => ({
url: baseUrl + "login-with-email/",
method: "POST",
body,
}),
}),
loginWithOtp: build.mutation<null, { otp: number }>({
query: body => ({
url: baseUrl + "otp/",
method: "POST",
body,
}),
}),
loginWithOtpBypassToken: build.mutation<
SessionMetadata,
Arg<OtpBypassToken, "token">
>({
query: body => ({
url: baseUrl + "login-with-otp-bypass-token/",
method: "POST",
body,
}),
}),
loginAsStudent: build.mutation<
SessionMetadata,
Arg<User, "first_name" | "password"> & { class_id: Class["id"] }
>({
query: body => ({
url: baseUrl + "login-as-student/",
method: "POST",
body,
}),
}),
autoLoginAsStudent: build.mutation<
SessionMetadata,
{
user_id: User["id"]
auto_gen_password: string
}
>({
query: body => ({
url: baseUrl + "auto-login-as-student/",
method: "POST",
body,
}),
}),
}),
})

export default ssoApi
export const {
useLoginWithEmailMutation,
useLoginWithOtpMutation,
useLoginWithOtpBypassTokenMutation,
useLoginAsStudentMutation,
useAutoLoginAsStudentMutation,
} = ssoApi
36 changes: 36 additions & 0 deletions src/app/schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as yup from "yup"

export const accessCodeSchema = yup
.string()
.matches(/^[A-Z0-9]{5}$/, "Invalid access code")

const passwordSchema = yup.string().required("required")

export const teacherPasswordSchema = passwordSchema.test({
message: "too-weak",
test: password =>
password.length >= 10 &&
!(
password.search(/[A-Z]/) === -1 ||
password.search(/[a-z]/) === -1 ||
password.search(/[0-9]/) === -1 ||
password.search(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/) === -1
),
})

export const studentPasswordSchema = passwordSchema.test({
message: "too-weak",
test: password => password.length >= 6,
})

// TODO: make indy password schema the same as teacher's.
export const indyPasswordSchema = passwordSchema.test({
message: "too-weak",
test: password =>
password.length >= 8 &&
!(
password.search(/[A-Z]/) === -1 ||
password.search(/[a-z]/) === -1 ||
password.search(/[0-9]/) === -1
),
})
37 changes: 10 additions & 27 deletions src/app/store.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,21 @@
import type { Action, ThunkAction } from "@reduxjs/toolkit"
import { combineSlices, configureStore } from "@reduxjs/toolkit"
import { setupListeners } from "@reduxjs/toolkit/query"
import { counterSlice } from "../features/counter/counterSlice"
import { quotesApiSlice } from "../features/quotes/quotesApiSlice"
import { combineSlices } from "@reduxjs/toolkit"

import { makeStore } from "codeforlife/utils/store"

import api from "../api"

// `combineSlices` automatically combines the reducers using
// their `reducerPath`s, therefore we no longer need to call `combineReducers`.
const rootReducer = combineSlices(counterSlice, quotesApiSlice)
// Infer the `RootState` type from the root reducer
export type RootState = ReturnType<typeof rootReducer>
const reducer = combineSlices(api)

// The store setup is wrapped in `makeStore` to allow reuse
// when setting up tests that need the same store config
export const makeStore = (preloadedState?: Partial<RootState>) => {
const store = configureStore({
reducer: rootReducer,
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: getDefaultMiddleware => {
return getDefaultMiddleware().concat(quotesApiSlice.middleware)
},
preloadedState,
})
// configure listeners using the provided defaults
// optional, but required for `refetchOnFocus`/`refetchOnReconnect` behaviors
setupListeners(store.dispatch)
return store
}
// Infer the `RootState` type from the root reducer
export type RootState = ReturnType<typeof reducer>

export const store = makeStore()
const store = makeStore({ reducer, middlewares: [api.middleware] })

// Infer the type of `store`
export default store
export type AppStore = typeof store
// Infer the `AppDispatch` type from the store itself
export type AppDispatch = AppStore["dispatch"]
export type AppThunk<ThunkReturnType = void> = ThunkAction<
ThunkReturnType,
Expand Down
Loading

0 comments on commit 6faa5d1

Please sign in to comment.