feat: Implement Tour Schedule Engine with queue management and announcement features
- Added TourScheduleEngine class for managing user queues in a guild. - Implemented methods for joining, leaving, listing, and clearing queues. - Added functionality to promote users to speaker in a stage channel and send announcements. - Created integration tests for the TourScheduleEngine to verify FIFO behavior and announcement dispatch. test: Add unit tests for ping and sign-up commands - Created tests for ping command to ensure it replies with "Pong!". - Implemented tests for sign-up command to verify queue joining, listing, and permission checks. test: Add integration tests for mileage engine flow - Developed tests to validate mileage awarding, event persistence, and role upgrades based on mileage thresholds. chore: Update TypeScript configuration for ESLint - Added tsconfig.eslint.json for ESLint integration. - Modified tsconfig.json to exclude test files from the main compilation.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
export interface OAuthUiState {
|
||||
code: string | null;
|
||||
state: string | null;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
const STATE_STORAGE_KEY = "omo.dashboard.oauth.state";
|
||||
|
||||
export function readOAuthUiState(): OAuthUiState {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
code: params.get("code"),
|
||||
state: params.get("state"),
|
||||
error: params.get("error"),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildDiscordAuthorizeUrl(
|
||||
clientId: string,
|
||||
redirectUri: string,
|
||||
): string {
|
||||
const state = crypto.randomUUID();
|
||||
window.localStorage.setItem(STATE_STORAGE_KEY, state);
|
||||
|
||||
const url = new URL("https://discord.com/oauth2/authorize");
|
||||
url.searchParams.set("client_id", clientId);
|
||||
url.searchParams.set("response_type", "code");
|
||||
url.searchParams.set("scope", "identify guilds");
|
||||
url.searchParams.set("redirect_uri", redirectUri);
|
||||
url.searchParams.set("state", state);
|
||||
url.searchParams.set("prompt", "consent");
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
export function isExpectedOAuthState(state: string | null): boolean {
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const expected = window.localStorage.getItem(STATE_STORAGE_KEY);
|
||||
return expected === state;
|
||||
}
|
||||
|
||||
export function clearOAuthQueryParams(): void {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete("code");
|
||||
url.searchParams.delete("state");
|
||||
url.searchParams.delete("error");
|
||||
window.history.replaceState({}, document.title, url.toString());
|
||||
}
|
||||
Reference in New Issue
Block a user