return user profile when fetching auth
parent
5884e90d96
commit
592f1c5b43
|
@ -1,9 +1,7 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { AppService } from './app.service';
|
||||
import { ApiOperation, ApiProperty, ApiResponse } from '@nestjs/swagger';
|
||||
import { ApiOperation, ApiProperty } from '@nestjs/swagger';
|
||||
import { META } from './meta';
|
||||
import { Auth, AuthData } from './auth/authdata.decorator';
|
||||
import { AuthenticationData } from './auth/auth.guard';
|
||||
import { ApiUserInfo } from 'lib';
|
||||
|
||||
export class ApiInfo {
|
||||
@ApiProperty()
|
||||
|
@ -19,12 +17,13 @@ export class AuthInfo {
|
|||
|
||||
@ApiProperty({ default: false })
|
||||
god: boolean;
|
||||
|
||||
@ApiProperty({ type: () => ApiUserInfo, nullable: true })
|
||||
profile: ApiUserInfo | null;
|
||||
}
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Fetch API configuration' })
|
||||
getHello(): ApiInfo {
|
||||
|
@ -32,17 +31,4 @@ export class AppController {
|
|||
version: META.version,
|
||||
};
|
||||
}
|
||||
|
||||
@Get('/auth')
|
||||
@Auth()
|
||||
@ApiOperation({ summary: 'Check authentication status' })
|
||||
@ApiResponse({ type: AuthInfo, status: 200 })
|
||||
getAuth(@AuthData() auth: AuthenticationData): AuthInfo {
|
||||
return {
|
||||
// Since the AuthGuard stops the request otherwise, we can assume the user is authenticated
|
||||
authenticated: true,
|
||||
user: auth.user,
|
||||
god: auth.god || false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import { Body, Controller, Ip, Post } from '@nestjs/common';
|
||||
import { ApiProperty, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { NoAuthentication } from './authdata.decorator';
|
||||
import { Body, Controller, Get, Ip, Post } from '@nestjs/common';
|
||||
import {
|
||||
ApiOperation,
|
||||
ApiProperty,
|
||||
ApiResponse,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { Auth, AuthData, NoAuthentication } from './authdata.decorator';
|
||||
import { AuthService } from './auth.service';
|
||||
import { AuthInfo } from 'src/app.controller';
|
||||
import { AuthenticationData } from './auth.guard';
|
||||
import { DatabaseService } from 'src/database/database.service';
|
||||
|
||||
export class LoginData {
|
||||
@ApiProperty({ description: 'The user ID you are trying to log in as' })
|
||||
|
@ -18,7 +26,23 @@ export class LoginResponse {
|
|||
@Controller('auth')
|
||||
@ApiTags('authentication')
|
||||
export class AuthController {
|
||||
constructor(private auth: AuthService) {}
|
||||
constructor(private auth: AuthService, private db: DatabaseService) {}
|
||||
|
||||
@Get('/')
|
||||
@Auth()
|
||||
@ApiOperation({ summary: 'Check authentication status' })
|
||||
@ApiResponse({ type: AuthInfo, status: 200 })
|
||||
async getAuth(@AuthData() auth: AuthenticationData): Promise<AuthInfo> {
|
||||
return {
|
||||
// Since the AuthGuard stops the request otherwise, we can assume the user is authenticated
|
||||
authenticated: true,
|
||||
user: auth.user,
|
||||
god: auth.god || false,
|
||||
profile: auth.user
|
||||
? (await this.db.getMessengers().getuserInfo({ id: auth.user })) || null
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
@Post('login')
|
||||
@NoAuthentication()
|
||||
|
|
|
@ -13,6 +13,8 @@ import {
|
|||
GetMutualServersRes,
|
||||
GetServerDetailsReq,
|
||||
GetServerDetailsRes,
|
||||
UserInfoReq,
|
||||
UserInfoRes,
|
||||
connectDb,
|
||||
connectRedis,
|
||||
createRedisIPCSender,
|
||||
|
@ -54,6 +56,11 @@ async function createMessengers(redis: AutomodRedis, rcvRedis: AutomodRedis) {
|
|||
GetServerDetailsReq,
|
||||
GetServerDetailsRes
|
||||
>('getServerDetails', redis, rcvRedis),
|
||||
getuserInfo: createRedisIPCSender<UserInfoReq, UserInfoRes>(
|
||||
'getUserInfo',
|
||||
redis,
|
||||
rcvRedis,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import {
|
|||
InfractionType,
|
||||
ModActionType,
|
||||
ServerLogCategory,
|
||||
UserInfoReq,
|
||||
UserInfoRes,
|
||||
canModifyServerSettings,
|
||||
connectRedis,
|
||||
createInfraction,
|
||||
|
@ -143,6 +145,24 @@ redisIPCHandler<GetServerDetailsReq, GetServerDetailsRes>(
|
|||
},
|
||||
);
|
||||
|
||||
redisIPCHandler<UserInfoReq, UserInfoRes | null>(
|
||||
"getUserInfo",
|
||||
client.redis,
|
||||
rcvRedis,
|
||||
async (msg) => {
|
||||
const user = await fetchUser(msg.id, client);
|
||||
return user
|
||||
? {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
discriminator: user.discriminator,
|
||||
displayName: user.displayName,
|
||||
avatarUrl: user.avatarURL,
|
||||
}
|
||||
: null;
|
||||
},
|
||||
);
|
||||
|
||||
export const authRequestsSender = createRedisIPCSender<
|
||||
AuthRequestInteractionReq,
|
||||
AuthRequestInteractionRes
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"author": "",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@nestjs/swagger": "^7.0.12",
|
||||
"log75": "^3.0.1",
|
||||
"mongodb": "^5.6.0",
|
||||
"redis": "^4.6.7",
|
||||
|
|
|
@ -23,5 +23,6 @@ export * from "./types/redis/create_infraction.js";
|
|||
export * from "./types/redis/get_mutual_servers.js";
|
||||
export * from "./types/redis/get_server_details.js";
|
||||
export * from "./types/redis/auth_request.js";
|
||||
export * from "./types/redis/user_info.js";
|
||||
|
||||
export const AUTH_TOKEN_LIFETIME = 1000 * 60 * 60 * 24;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
|
||||
export class ApiUserInfo {
|
||||
@ApiProperty({ type: String })
|
||||
id: string;
|
||||
|
||||
@ApiProperty({ type: String })
|
||||
username: string;
|
||||
|
||||
@ApiProperty({ type: String })
|
||||
discriminator: string;
|
||||
|
||||
@ApiProperty({ type: String, nullable: true })
|
||||
displayName?: string;
|
||||
|
||||
@ApiProperty({ type: String, nullable: true })
|
||||
avatarUrl?: string;
|
||||
}
|
||||
|
||||
export type UserInfoReq = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type UserInfoRes = ApiUserInfo | null;
|
|
@ -11,6 +11,8 @@
|
|||
"esModuleInterop": true,
|
||||
"isolatedModules": true,
|
||||
"resolveJsonModule": true,
|
||||
"strictPropertyInitialization": false
|
||||
"strictPropertyInitialization": false,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,36 +13,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/auth": {
|
||||
"get": {
|
||||
"operationId": "getAuth",
|
||||
"summary": "Check authentication status",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AuthInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "No valid authentication presented"
|
||||
},
|
||||
"403": {
|
||||
"description": "The user does not have access to the resource"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/servers/{server}/infractions": {
|
||||
"get": {
|
||||
"operationId": "listInfractions",
|
||||
|
@ -281,6 +251,39 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/auth": {
|
||||
"get": {
|
||||
"operationId": "getAuth",
|
||||
"summary": "Check authentication status",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AuthInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "No valid authentication presented"
|
||||
},
|
||||
"403": {
|
||||
"description": "The user does not have access to the resource"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"authentication"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/auth/login": {
|
||||
"post": {
|
||||
"operationId": "login",
|
||||
|
@ -416,26 +419,6 @@
|
|||
}
|
||||
},
|
||||
"schemas": {
|
||||
"AuthInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authenticated": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"user": {
|
||||
"type": "string"
|
||||
},
|
||||
"god": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"authenticated",
|
||||
"user",
|
||||
"god"
|
||||
]
|
||||
},
|
||||
"CreateInfractionData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -554,6 +537,64 @@
|
|||
"config"
|
||||
]
|
||||
},
|
||||
"ApiUserInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"discriminator": {
|
||||
"type": "string"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"avatarUrl": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"username",
|
||||
"discriminator",
|
||||
"displayName",
|
||||
"avatarUrl"
|
||||
]
|
||||
},
|
||||
"AuthInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authenticated": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"user": {
|
||||
"type": "string"
|
||||
},
|
||||
"god": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"profile": {
|
||||
"nullable": true,
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ApiUserInfo"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"authenticated",
|
||||
"user",
|
||||
"god",
|
||||
"profile"
|
||||
]
|
||||
},
|
||||
"LoginData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// This file was auto-generated by @insertish/oapi!
|
||||
export const pathResolve = {"1":[[""],["auth"],["servers"],["test"]],"2":[["servers",["{server}"]],["auth","login"]],"3":[["servers",["{server}"],"infractions"]],"4":[["servers",["{server}"],"infractions",["{id}"]]]};
|
||||
export const queryParams = {"/":{"get":[]},"/auth":{"get":[]},"/servers/{server}/infractions":{"get":["user","mod","limit","before","after"],"post":[]},"/servers/{server}/infractions/{id}":{"get":[]},"/servers":{"get":[]},"/servers/{server}":{"get":[]},"/auth/login":{"post":[]},"/test":{"get":[],"post":[],"patch":[],"put":[],"delete":[]}};
|
||||
export const pathResolve = {"1":[[""],["servers"],["auth"],["test"]],"2":[["servers",["{server}"]],["auth","login"]],"3":[["servers",["{server}"],"infractions"]],"4":[["servers",["{server}"],"infractions",["{id}"]]]};
|
||||
export const queryParams = {"/":{"get":[]},"/servers/{server}/infractions":{"get":["user","mod","limit","before","after"],"post":[]},"/servers/{server}/infractions/{id}":{"get":[]},"/servers":{"get":[]},"/servers/{server}":{"get":[]},"/auth":{"get":[]},"/auth/login":{"post":[]},"/test":{"get":[],"post":[],"patch":[],"put":[],"delete":[]}};
|
|
@ -2,7 +2,6 @@
|
|||
import { paths } from './schema';
|
||||
export type APIRoutes =
|
||||
| { method: 'get', path: `/`, parts: 1, params: undefined, response: undefined }
|
||||
| { method: 'get', path: `/auth`, parts: 1, params: undefined, response: paths['/auth']['get']['responses']['200']['content']['application/json'] }
|
||||
| { method: 'get', path: `/servers/${string}/infractions`, parts: 3, params: paths['/servers/{server}/infractions']['get']['parameters']['query'], response: undefined }
|
||||
| { method: 'get', path: '-/servers/{server}/infractions', parts: 3, params: paths['/servers/{server}/infractions']['get']['parameters']['query'], response: undefined }
|
||||
| { method: 'post', path: `/servers/${string}/infractions`, parts: 3, params: paths['/servers/{server}/infractions']['post']['requestBody']['content']['application/json'], response: undefined }
|
||||
|
@ -12,6 +11,7 @@ export type APIRoutes =
|
|||
| { method: 'get', path: `/servers`, parts: 1, params: undefined, response: undefined }
|
||||
| { method: 'get', path: `/servers/${string}`, parts: 2, params: undefined, response: undefined }
|
||||
| { method: 'get', path: '-/servers/{server}', parts: 2, params: undefined, response: undefined }
|
||||
| { method: 'get', path: `/auth`, parts: 1, params: undefined, response: paths['/auth']['get']['responses']['200']['content']['application/json'] }
|
||||
| { method: 'post', path: `/auth/login`, parts: 2, params: paths['/auth/login']['post']['requestBody']['content']['application/json'], response: undefined }
|
||||
| { method: 'get', path: `/test`, parts: 1, params: undefined, response: undefined }
|
||||
| { method: 'post', path: `/test`, parts: 1, params: undefined, response: undefined }
|
||||
|
|
|
@ -9,10 +9,6 @@ export interface paths {
|
|||
/** Fetch API configuration */
|
||||
get: operations["getHello"];
|
||||
};
|
||||
"/auth": {
|
||||
/** Check authentication status */
|
||||
get: operations["getAuth"];
|
||||
};
|
||||
"/servers/{server}/infractions": {
|
||||
/** Fetch a list of infractions */
|
||||
get: operations["listInfractions"];
|
||||
|
@ -31,6 +27,10 @@ export interface paths {
|
|||
/** Fetch details about a specific server */
|
||||
get: operations["getServer"];
|
||||
};
|
||||
"/auth": {
|
||||
/** Check authentication status */
|
||||
get: operations["getAuth"];
|
||||
};
|
||||
"/auth/login": {
|
||||
post: operations["login"];
|
||||
};
|
||||
|
@ -47,12 +47,6 @@ export type webhooks = Record<string, never>;
|
|||
|
||||
export interface components {
|
||||
schemas: {
|
||||
AuthInfo: {
|
||||
authenticated: boolean;
|
||||
user: string;
|
||||
/** @default false */
|
||||
god: boolean;
|
||||
};
|
||||
CreateInfractionData: {
|
||||
user: string;
|
||||
reason: string;
|
||||
|
@ -84,6 +78,20 @@ export interface components {
|
|||
info: components["schemas"]["ServerInfo"];
|
||||
config: components["schemas"]["ServerConfig"];
|
||||
};
|
||||
ApiUserInfo: {
|
||||
id: string;
|
||||
username: string;
|
||||
discriminator: string;
|
||||
displayName: string | null;
|
||||
avatarUrl: string | null;
|
||||
};
|
||||
AuthInfo: {
|
||||
authenticated: boolean;
|
||||
user: string;
|
||||
/** @default false */
|
||||
god: boolean;
|
||||
profile: components["schemas"]["ApiUserInfo"] | null;
|
||||
};
|
||||
LoginData: {
|
||||
/** @description The user ID you are trying to log in as */
|
||||
user: string;
|
||||
|
@ -110,20 +118,6 @@ export interface operations {
|
|||
200: never;
|
||||
};
|
||||
};
|
||||
/** Check authentication status */
|
||||
getAuth: {
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["AuthInfo"];
|
||||
};
|
||||
};
|
||||
/** @description No valid authentication presented */
|
||||
401: never;
|
||||
/** @description The user does not have access to the resource */
|
||||
403: never;
|
||||
};
|
||||
};
|
||||
/** Fetch a list of infractions */
|
||||
listInfractions: {
|
||||
parameters: {
|
||||
|
@ -217,6 +211,20 @@ export interface operations {
|
|||
};
|
||||
};
|
||||
};
|
||||
/** Check authentication status */
|
||||
getAuth: {
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["AuthInfo"];
|
||||
};
|
||||
};
|
||||
/** @description No valid authentication presented */
|
||||
401: never;
|
||||
/** @description The user does not have access to the resource */
|
||||
403: never;
|
||||
};
|
||||
};
|
||||
login: {
|
||||
requestBody: {
|
||||
content: {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// This file was auto-generated by @insertish/oapi!
|
||||
import { components } from './schema';
|
||||
export type AuthInfo = components['schemas']['AuthInfo'];
|
||||
export type CreateInfractionData = components['schemas']['CreateInfractionData'];
|
||||
export type ServerInfo = components['schemas']['ServerInfo'];
|
||||
export type GetServersResponse = components['schemas']['GetServersResponse'];
|
||||
export type ServerLogsConfig = components['schemas']['ServerLogsConfig'];
|
||||
export type ServerConfig = components['schemas']['ServerConfig'];
|
||||
export type ServerDetails = components['schemas']['ServerDetails'];
|
||||
export type ApiUserInfo = components['schemas']['ApiUserInfo'];
|
||||
export type AuthInfo = components['schemas']['AuthInfo'];
|
||||
export type LoginData = components['schemas']['LoginData'];
|
||||
export type LoginResponse = components['schemas']['LoginResponse'];;
|
|
@ -283,6 +283,9 @@ importers:
|
|||
|
||||
lib:
|
||||
dependencies:
|
||||
'@nestjs/swagger':
|
||||
specifier: ^7.0.12
|
||||
version: 7.0.12(@nestjs/common@10.0.0)(@nestjs/core@10.0.0)(class-transformer@0.5.1)(class-validator@0.14.0)(reflect-metadata@0.1.13)
|
||||
log75:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
|
@ -366,6 +369,9 @@ importers:
|
|||
lib:
|
||||
specifier: workspace:*
|
||||
version: link:../lib
|
||||
localforage:
|
||||
specifier: ^1.10.0
|
||||
version: 1.10.0
|
||||
next:
|
||||
specifier: 13.4.10
|
||||
version: 13.4.10(react-dom@18.2.0)(react@18.2.0)
|
||||
|
@ -4636,6 +4642,10 @@ packages:
|
|||
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
/immediate@3.0.6:
|
||||
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||
dev: false
|
||||
|
||||
/import-fresh@3.3.0:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -5561,6 +5571,12 @@ packages:
|
|||
/libphonenumber-js@1.10.37:
|
||||
resolution: {integrity: sha512-Z10PCaOCiAxbUxLyR31DNeeNugSVP6iv/m7UrSKS5JHziEMApJtgku4e9Q69pzzSC9LnQiM09sqsGf2ticZnMw==}
|
||||
|
||||
/lie@3.1.1:
|
||||
resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
|
||||
dependencies:
|
||||
immediate: 3.0.6
|
||||
dev: false
|
||||
|
||||
/lilconfig@2.1.0:
|
||||
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -5574,6 +5590,12 @@ packages:
|
|||
engines: {node: '>=6.11.5'}
|
||||
dev: true
|
||||
|
||||
/localforage@1.10.0:
|
||||
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
|
||||
dependencies:
|
||||
lie: 3.1.1
|
||||
dev: false
|
||||
|
||||
/locate-path@5.0.0:
|
||||
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"eslint": "8.45.0",
|
||||
"eslint-config-next": "13.4.10",
|
||||
"lib": "workspace:*",
|
||||
"localforage": "^1.10.0",
|
||||
"next": "13.4.10",
|
||||
"oapilib": "workspace:*",
|
||||
"postcss": "8.4.26",
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
"use client";
|
||||
|
||||
import { useBearStore } from "@/components/state";
|
||||
import { API, AuthInfo } from "oapilib";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function Auth() {
|
||||
const state = useBearStore();
|
||||
const [authInfo, setAuthInfo] = useState<AuthInfo | undefined>(state.auth);
|
||||
|
||||
useEffect(() => {
|
||||
state.api = new API({
|
||||
authentication: { headers: { Authorization: "Bearer banana" } },
|
||||
});
|
||||
|
||||
if (!authInfo) {
|
||||
state.api
|
||||
.get("/auth")
|
||||
.then((res) => setAuthInfo(res))
|
||||
.catch((e) => alert(e));
|
||||
}
|
||||
});
|
||||
|
||||
return authInfo ? (
|
||||
<div>
|
||||
<h1>hi</h1>
|
||||
<p>{authInfo.profile?.displayName}</p>
|
||||
</div>
|
||||
) : (
|
||||
<span>real</span>
|
||||
);
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { useBearStore } from "@/components/state";
|
||||
import "./globals.css";
|
||||
import type { Metadata } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
|
@ -5,11 +6,11 @@ import { Inter } from "next/font/google";
|
|||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: "AutoMod",
|
||||
description: "Revolt's most hated moderation bot",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { API } from "oapilib";
|
||||
import { API, AuthInfo } from "oapilib";
|
||||
import { create } from "zustand";
|
||||
|
||||
type State = {
|
||||
api: API;
|
||||
auth?: AuthInfo;
|
||||
};
|
||||
|
||||
export const useBearStore = create<State>((set) => ({
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import localforage from "localforage";
|
||||
|
||||
type CredentialsData = {
|
||||
token: string | null;
|
||||
};
|
||||
|
||||
export async function setCredentials({ token }: CredentialsData) {
|
||||
await localforage.setItem("api_token", token);
|
||||
}
|
||||
|
||||
export async function getCredentials(): Promise<CredentialsData> {
|
||||
return {
|
||||
token: await localforage.getItem("api_token"),
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue