Gisle Aune
2 years ago
37 changed files with 332 additions and 553 deletions
-
130.drone.yml
-
2Dockerfile
-
140cmd/stufflog3-local/main.go
-
43cmd/stufflog3/main.go
-
174frontend/package-lock.json
-
1frontend/package.json
-
5frontend/src/app.d.ts
-
68frontend/src/hooks.ts
-
0frontend/src/lib/assets/background.jpg
-
6frontend/src/lib/clients/sl3.ts
-
4frontend/src/lib/components/contexts/ItemListContext.svelte
-
4frontend/src/lib/components/contexts/ItemMultiListContext.svelte
-
4frontend/src/lib/components/contexts/ProjectContext.svelte
-
4frontend/src/lib/components/contexts/ProjectListContext.svelte
-
6frontend/src/lib/components/contexts/ScopeListContext.svelte
-
4frontend/src/lib/components/contexts/SprintListContext.svelte
-
4frontend/src/lib/modals/DeletionModal.svelte
-
6frontend/src/lib/modals/ItemAcquireModal.svelte
-
10frontend/src/lib/modals/ItemCreateModal.svelte
-
9frontend/src/lib/modals/ProjectCreateEditModal.svelte
-
12frontend/src/lib/modals/RequirementCreateModal.svelte
-
8frontend/src/lib/modals/ScopeCreateUpdateModal.svelte
-
16frontend/src/lib/modals/SprintCreateUpdateModal.svelte
-
11frontend/src/lib/modals/StatCreateEditModal.svelte
-
9frontend/src/routes/[scope=prettyid]/__layout.svelte
-
4frontend/src/routes/[scope=prettyid]/history/[interval].svelte
-
16frontend/src/routes/[scope=prettyid]/overview.svelte
-
4frontend/src/routes/[scope=prettyid]/projects/[project=prettyid].svelte
-
4frontend/src/routes/[scope=prettyid]/sprints/[interval].svelte
-
32frontend/src/routes/__layout.svelte
-
4frontend/src/routes/api/[...any].ts
-
16frontend/src/routes/index.svelte
-
28frontend/src/routes/login.svelte
-
12frontend/svelte.config.js
-
35frontend/tsconfig.json
-
2go.mod
-
48serverless.yml
@ -1,140 +0,0 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/cognitoauth" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/httpapi" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/auth" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/items" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/projects" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/sprints" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/stats" |
|||
"github.com/gin-gonic/gin" |
|||
"log" |
|||
"os" |
|||
"os/signal" |
|||
"strconv" |
|||
"syscall" |
|||
) |
|||
|
|||
func main() { |
|||
db, err := mysql.Connect( |
|||
os.Getenv("STUFFLOG3_MYSQL_HOST"), |
|||
envInt("STUFFLOG3_MYSQL_PORT"), |
|||
os.Getenv("STUFFLOG3_MYSQL_USERNAME"), |
|||
os.Getenv("STUFFLOG3_MYSQL_PASSWORD"), |
|||
os.Getenv("STUFFLOG3_MYSQL_SCHEMA"), |
|||
) |
|||
if err != nil { |
|||
log.Println("Failed to open database:", err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
cognitoAuth, err := cognitoauth.New( |
|||
os.Getenv("STUFFLOG3_AWS_REGION"), |
|||
os.Getenv("STUFFLOG3_AWS_CLIENT_ID"), |
|||
os.Getenv("STUFFLOG3_AWS_CLIENT_SECRET"), |
|||
os.Getenv("STUFFLOG3_AWS_POOL_ID"), |
|||
os.Getenv("STUFFLOG3_AWS_POOL_CLIENT_ID"), |
|||
os.Getenv("STUFFLOG3_AWS_POOL_CLIENT_SECRET"), |
|||
) |
|||
if err != nil { |
|||
log.Println("Failed to setup cognito:", err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
authService := &auth.Service{ |
|||
Provider: cognitoAuth, |
|||
} |
|||
scopesService := &scopes.Service{ |
|||
Auth: authService, |
|||
Repository: db.Scopes(), |
|||
StatsLister: db.Stats(), |
|||
} |
|||
statsService := &stats.Service{ |
|||
Scopes: scopesService, |
|||
Repository: db.Stats(), |
|||
} |
|||
itemsService := &items.Service{ |
|||
Auth: authService, |
|||
Scopes: scopesService, |
|||
Stats: statsService, |
|||
Repository: db.Items(), |
|||
RequirementFetcher: db.Projects(), |
|||
ProjectFetcher: db.Projects(), |
|||
} |
|||
projectsService := &projects.Service{ |
|||
Auth: authService, |
|||
Scopes: scopesService, |
|||
Stats: statsService, |
|||
Items: itemsService, |
|||
Repository: db.Projects(), |
|||
} |
|||
sprintsService := &sprints.Service{ |
|||
Scopes: scopesService, |
|||
Items: itemsService, |
|||
Projects: projectsService, |
|||
Repository: db.Sprints(), |
|||
} |
|||
|
|||
server := gin.New() |
|||
httpapi.Auth(server.Group("/api/v1/auth"), authService) |
|||
apiV1 := server.Group("/api/v1") |
|||
if os.Getenv("STUFFLOG3_USE_DUMMY_USER") == "true" { |
|||
log.Println("Using dummy UUID") |
|||
apiV1.Use(httpapi.DummyMiddleware(authService, "c11230be-4912-4313-83b0-410a248b5bd1")) |
|||
} else { |
|||
apiV1.Use(httpapi.JwtValidatorMiddleware(authService)) |
|||
} |
|||
apiV1Scopes := apiV1.Group("/scopes") |
|||
httpapi.Scopes(apiV1Scopes, scopesService) |
|||
apiV1ScopesSub := apiV1Scopes.Group("/:scope_id") |
|||
apiV1ScopesSub.Use(httpapi.ScopeMiddleware(scopesService, authService)) |
|||
httpapi.Projects(apiV1ScopesSub.Group("/projects"), projectsService) |
|||
httpapi.Items(apiV1ScopesSub.Group("/items"), itemsService) |
|||
httpapi.Sprints(apiV1ScopesSub.Group("/sprints"), sprintsService) |
|||
httpapi.Stats(apiV1ScopesSub.Group("/stats"), statsService) |
|||
apiV1AllScopes := apiV1.Group("/all-scopes") |
|||
apiV1AllScopes.Use(httpapi.AllScopeMiddleware(scopesService, authService)) |
|||
httpapi.ItemsAllScopes(apiV1AllScopes.Group("/items"), itemsService) |
|||
httpapi.SprintsAllScopes(apiV1AllScopes.Group("/sprints"), sprintsService) |
|||
|
|||
exitSignal := make(chan os.Signal) |
|||
signal.Notify(exitSignal, os.Interrupt, os.Kill, syscall.SIGTERM) |
|||
|
|||
errCh := make(chan error) |
|||
go func() { |
|||
err := server.Run(":8239") |
|||
if err != nil { |
|||
errCh <- err |
|||
} |
|||
}() |
|||
|
|||
select { |
|||
case sig := <-exitSignal: |
|||
{ |
|||
log.Println("Received signal", sig) |
|||
os.Exit(0) |
|||
} |
|||
case err := <-errCh: |
|||
{ |
|||
log.Println("Server run failed:", err) |
|||
os.Exit(2) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func envInt(key string) int { |
|||
value := os.Getenv(key) |
|||
if value == "" { |
|||
return 0 |
|||
} |
|||
|
|||
intValue, err := strconv.Atoi(value) |
|||
if err != nil { |
|||
return 0 |
|||
} |
|||
|
|||
return intValue |
|||
} |
@ -1,67 +1,3 @@ |
|||
import cookie from 'cookie'; |
|||
import { Amplify, withSSRContext } from 'aws-amplify'; |
|||
import type { GetSession, Handle } from '@sveltejs/kit'; |
|||
|
|||
Amplify.configure({ |
|||
Auth: { |
|||
region: process.env.STUFFLOG3_AWS_POOL_REGION, |
|||
userPoolId: process.env.STUFFLOG3_AWS_POOL_ID, |
|||
userPoolWebClientId: process.env.STUFFLOG3_AWS_POOL_PUBLIC_CLIENT_ID, |
|||
}, |
|||
ssr: true, |
|||
}); |
|||
|
|||
|
|||
export const getSession: GetSession = ({ locals, request }) => { |
|||
return { |
|||
idToken: locals.idToken, |
|||
user: locals.user, |
|||
req: { headers: { cookie: request.headers.get("Cookie") } }, |
|||
amplifyConfig: { |
|||
region: process.env.STUFFLOG3_AWS_POOL_REGION, |
|||
userPoolId: process.env.STUFFLOG3_AWS_POOL_ID, |
|||
userPoolWebClientId: process.env.STUFFLOG3_AWS_POOL_PUBLIC_CLIENT_ID, |
|||
}, |
|||
}; |
|||
}; |
|||
|
|||
export const handle: Handle = async({ event, resolve }) => { |
|||
const {Auth} = withSSRContext({ |
|||
req: { headers: { cookie: event.request.headers.get("Cookie") } } |
|||
}); |
|||
|
|||
const newCookies = {}; |
|||
|
|||
try { |
|||
const curr = await Auth.currentAuthenticatedUser(); |
|||
event.locals.idToken = curr.signInUserSession?.idToken?.jwtToken; |
|||
if (event.locals.idToken != null) { |
|||
event.locals.user = { |
|||
id: curr.signInUserSession.idToken.payload["sub"], |
|||
name: curr.signInUserSession.idToken.payload["cognito:username"], |
|||
} |
|||
} |
|||
|
|||
const store = curr?.storage?.store || {}; |
|||
const cookies = cookie.parse(event.request.headers.get("Cookie")); |
|||
for (const key in store) { |
|||
if (store[key] != cookies[key]) { |
|||
newCookies[key] = store[key] |
|||
} |
|||
} |
|||
} catch(err) { |
|||
console.warn(err) |
|||
} |
|||
|
|||
const response = await resolve(event); |
|||
|
|||
for (const key in newCookies) { |
|||
response.headers.append("Set-Cookie", cookie.serialize(key, newCookies[key], { |
|||
path: "/", |
|||
maxAge: 8640000, |
|||
expires: new Date(Date.now() + 8640000000), |
|||
})); |
|||
} |
|||
|
|||
return response; |
|||
export async function handle({ event, resolve }) { |
|||
return resolve(event, { ssr: false }); |
|||
} |
Before Width: 1920 | Height: 1080 | Size: 112 KiB After Width: 1920 | Height: 1080 | Size: 112 KiB |
@ -1,36 +1,3 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"moduleResolution": "node", |
|||
"module": "es2020", |
|||
"lib": ["es2020", "DOM"], |
|||
"target": "es2020", |
|||
/** |
|||
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript |
|||
to enforce using \`import type\` instead of \`import\` for Types. |
|||
*/ |
|||
"importsNotUsedAsValues": "error", |
|||
/** |
|||
TypeScript doesn't know about import usages in the template because it only sees the |
|||
script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher. |
|||
*/ |
|||
"preserveValueImports": true, |
|||
"isolatedModules": true, |
|||
"resolveJsonModule": true, |
|||
/** |
|||
To have warnings/errors of the Svelte compiler at the correct position, |
|||
enable source maps by default. |
|||
*/ |
|||
"sourceMap": true, |
|||
"esModuleInterop": true, |
|||
"skipLibCheck": true, |
|||
"forceConsistentCasingInFileNames": true, |
|||
"baseUrl": ".", |
|||
"allowJs": true, |
|||
"checkJs": true, |
|||
"paths": { |
|||
"$lib": ["src/lib"], |
|||
"$lib/*": ["src/lib/*"] |
|||
} |
|||
}, |
|||
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"] |
|||
"extends": "./.svelte-kit/tsconfig.json" |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue