koa#ParameterizedContext TypeScript Examples

The following examples show how to use koa#ParameterizedContext. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: comments.ts    From Corsace with MIT License 6 votes vote down vote up
async function isCommentOwner (ctx: ParameterizedContext, next: Next): Promise<any> {
    const comment = await UserComment.findOneOrFail({ 
        where: {
            ID: ctx.params.id,
        },
        relations: ["commenter"],
    });

    if (comment.commenterID !== ctx.state.user.ID) {
        return ctx.body = {
            error: "Not your comment",
        };
    }

    ctx.state.comment = comment;
    await next();
}
Example #2
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
function hasRole (section: string, role: string) {
    return async (ctx: ParameterizedContext, next: Next): Promise<void> => {
        const member = await getMember(ctx.state.user.discord.userID);
        if (
            member && 
            (
                member.roles.cache.has(config.discord.roles[section][role]) || 
                member.roles.cache.has(config.discord.roles.corsace.corsace) || 
                (role === "corsace" ? false : member.roles.cache.has(config.discord.roles.corsace.headStaff))
            )
        ) {
            await next();
            return;
        } 
        
        ctx.body = { error: "User does not have the " + role + " role!" };
        return;
    };
}
Example #3
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
async function isStaff (ctx: ParameterizedContext, next: Next): Promise<void> {
    const member = await getMember(ctx.state.user.discord.userID);
    if (member) {
        const roles = [
            config.discord.roles.corsace.corsace,
            config.discord.roles.corsace.headStaff,
            config.discord.roles.corsace.staff,
        ];
        for (const role of roles)
            if (member.roles.cache.has(role)) {
                await next();
                return;
            }
    }
    
    ctx.body = { error: "User is not a staff member!" };
    return; 
}
Example #4
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
function hasRoles (roles: discordRoleInfo[]) {
    return async (ctx: ParameterizedContext, next: Next): Promise<void> => {
        const member = await getMember(ctx.state.user.discord.userID);
        if (!member) {
            ctx.body = { error: "Could not obtain any discord user!" };
            return;
        }

        if (
            member.roles.cache.has(config.discord.roles.corsace.corsace) || 
            (roles.some(role => role.section == "corsace" && role.role == "corsace") ? false : member.roles.cache.has(config.discord.roles.corsace.headStaff))
        ) {
            await next();
            return;
        }
        for (const role of roles) {
            if (member.roles.cache.has(config.discord.roles[role.section][role.role]))
            {
                await next();
                return;
            }
        }
        
        ctx.body = { error: "User does not have any of the required roles!" };
        return;
    };
}
Example #5
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
// General middlewares
async function isLoggedIn (ctx: ParameterizedContext, next: Next): Promise<void> {
    if (!ctx.state.user) {
        ctx.body = { error: "User is not logged in via osu!" };
        return;
    }

    await next();
}
Example #6
Source File: Responder.ts    From node-experience with MIT License 6 votes vote down vote up
public async send(data: any, ctx: ParameterizedContext, status: IHttpStatusCode, transformer: Transformer = null)
    {
        if (!transformer)
        {
            ctx.status = status.code;
            return ctx.body = {
                data
            };
        }

        data = await transformer.handle(data);

        ctx.status = status.code;
        return ctx.body = this.formatResponder.getFormatData(data, null);
    }
Example #7
Source File: Responder.ts    From node-experience with MIT License 6 votes vote down vote up
public async paginate(paginator: IPaginator, ctx: ParameterizedContext, status: IHttpStatusCode, transformer: Transformer = null)
    {
        const data = await paginator.paginate();
        const metadata = paginator.getMetadata();
        const result = this.formatResponder.getFormatData(data, metadata);

        if (!transformer)
        {
            ctx.status = status.code;
            return ctx.body = {
                data,
                metadata
            };
        }

        result.data = await transformer.handle(data);

        if (paginator.getExist())
        {
            const paginatorTransformer = new PaginatorTransformer();
            paginator = await paginatorTransformer.handle(paginator);

            const pagination = { pagination: paginator };

            Object.assign(result, pagination);
        }

        ctx.status = status.code;
        return ctx.body = result;
    }
Example #8
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
async function isResults (ctx: ParameterizedContext, next: Next): Promise<any> {
    if (ctx.state.mca.currentPhase() === "results") {
        await next();
        return;
    }

    const member = await getMember(ctx.state.user.discord.userID);
    if (!member) {
        ctx.body = { error: "Not the right time" };
        return;
    }
    if (
        member.roles.cache.has(config.discord.roles.corsace.corsace) ||
        member.roles.cache.has(config.discord.roles.corsace.core) ||
        member.roles.cache.has(config.discord.roles.corsace.headStaff) ||
        member.roles.cache.has(config.discord.roles.mca.standard) ||
        member.roles.cache.has(config.discord.roles.mca.taiko) ||
        member.roles.cache.has(config.discord.roles.mca.fruits) ||
        member.roles.cache.has(config.discord.roles.mca.mania) ||
        member.roles.cache.has(config.discord.roles.mca.storyboard)
    ) {
        await next();
        return;
    }
}
Example #9
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
function isPhaseStarted (phase: string) {
    return async (ctx: ParameterizedContext, next: Next): Promise<void> => {
        const mca: MCA = ctx.state.mca;
        const now = new Date();

        if (now < mca[phase].start) {
            ctx.body = { error: "Not the right time" };
            return;
        }

        await next();
        return;
    };
}
Example #10
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
function isPhase (phase: string) {
    return async (ctx: ParameterizedContext, next: Next): Promise<void> => {
        const mca: MCA = ctx.state.mca;
        const now = new Date();

        if (now < mca[phase].start || now > mca[phase].end) {
            ctx.body = { error: "Not the right time" };
            return;
        }

        await next();
        return;
    };
}
Example #11
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
async function validatePhaseYear (ctx: ParameterizedContext, next: Next): Promise<any> {
    try {
        let year = ctx.params.year;
        if (!year || !/^20[0-9]{2}$/.test(year)) {
            ctx.state.mca = await MCA.current();
            year = ctx.state.mca.year;
        } else {
            year = parseInt(year, 10);
            ctx.state.mca = await MCA.findOneOrFail(year);
        }

        ctx.state.year = year;
    } catch (e) {
        ctx.body = { error: "No Currently running MCA found." };
        return;
    }
    
    await next();
}
Example #12
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
async function currentMCA (ctx: ParameterizedContext, next: Next): Promise<any> {
    const mca = await MCA.findOne({
        results: MoreThanOrEqual(new Date()),
        nomination: {
            start: LessThanOrEqual(new Date()),
        },
    });

    if (!mca) {
        return ctx.body = {
            error: "No MCA found for this year",
        };
    }

    ctx.state.mca = mca;

    await next();
}
Example #13
Source File: middleware.ts    From Corsace with MIT License 6 votes vote down vote up
async function isEligible (ctx: ParameterizedContext, next: Next): Promise<void> {
    const mca: MCA = ctx.state.mca;
    const user: User = ctx.state.user;
    
    if (user.mcaEligibility.find(e => e.year === mca.year)) {
        return await next();
    }
    
    ctx.body = {
        error: "User wasn't active last year!",
    };
}
Example #14
Source File: comments.ts    From Corsace with MIT License 6 votes vote down vote up
async function canComment (ctx: ParameterizedContext, next: Next): Promise<any> {
    if (!ctx.state.user.canComment) {
        return ctx.body = {
            error: "You cannot comment",
        };
    }
    
    await next();
}
Example #15
Source File: AuthUser.ts    From node-experience with MIT License 5 votes vote down vote up
AuthUser  = <T extends Auth = Auth >(request: Request | ParameterizedContext |any, type: TypeAuth = 'authUser'): T =>
{
    return request[type];
}
Example #16
Source File: Responder.ts    From node-experience with MIT License 5 votes vote down vote up
public error(error: ErrorHttpException, ctx: ParameterizedContext, status: IHttpStatusCode)
    {
        ctx.status = status.code;
        return ctx.body = this.formatError.getFormat(error);
    }
Example #17
Source File: LoggerMiddleware.ts    From node-experience with MIT License 5 votes vote down vote up
LoggerMiddleware = async(ctx: ParameterizedContext, next: Next) =>
{
    Logger.debug(`${ctx.method}: ${ctx.path} - ${ctx.ip}`);
    await next();
}
Example #18
Source File: index.ts    From aiyou-wechaty-robot with Mozilla Public License 2.0 5 votes vote down vote up
router.get('/', async (ctx: ParameterizedContext) => {
  await ctx.render('index', {
    title: 'Welcome to aiyou-wechaty-robot nodejs api!',
  });
});
Example #19
Source File: middleware.ts    From Corsace with MIT License 5 votes vote down vote up
async function isLoggedInDiscord (ctx: ParameterizedContext, next: Next): Promise<void> {
    if (!ctx.state.user?.discord?.userID) {
        ctx.body = { error: "User is not logged in via discord!" };
        return; 
    }

    await next();
}
Example #20
Source File: osu.ts    From Corsace with MIT License 5 votes vote down vote up
osuRouter.get("/", redirectToMainDomain, async (ctx: ParameterizedContext<any>, next) => {
    const baseURL = ctx.query.site ? (config[ctx.query.site] ? config[ctx.query.site].publicUrl : config.corsace.publicUrl) : "";
    const params = ctx.query.redirect ?? "";
    const redirectURL = baseURL + params ?? "back";
    ctx.cookies.set("redirect", redirectURL, { overwrite: true });
    await next();
}, passport.authenticate("oauth2", { scope: ["identify", "public", "friends.read"] }));
Example #21
Source File: middleware.ts    From Corsace with MIT License 5 votes vote down vote up
export async function redirectToMainDomain (ctx: ParameterizedContext, next: Next): Promise<void> {
    // Redirect to the main host (where user gets redirected post-oauth) to apply redirect cookie on the right domain
    if(ctx.host !== mainHost) {
        ctx.redirect(`${config[process.env.NODE_ENV === "production" ? "corsace" : "api"].publicUrl}${ctx.originalUrl}`);
        return;
    }
    await next();
}
Example #22
Source File: discord.ts    From Corsace with MIT License 5 votes vote down vote up
discordRouter.get("/callback", async (ctx: ParameterizedContext, next) => {
    return await passport.authenticate("discord", { scope: ["identify", "guilds.join"], failureRedirect: "/" }, async (err, user) => {
        if (user) {
            if (ctx.state.user) {
                ctx.state.user.discord = user.discord;
                user = ctx.state.user;
            } else if (!user.osu)
            {
                ctx.body = { error: "There is no osu! account linked to this discord account! Please register via osu! first." };
                return;
            }

            await user.save();

            try {
                // Add user to server if they aren't there yet
                const guild = await discordGuild();
                try {
                    const discordUser = await guild.members.fetch(user.discord.userID);
                    await Promise.all([
                        discordUser.setNickname(user.osu.username),
                        discordUser.roles.add(config.discord.roles.corsace.verified),
                    ]);
                } catch (e) {
                    await guild.members.add(user.discord.userID, {
                        accessToken: user.discord.accessToken,
                        nick: user.osu.username,
                        roles: [config.discord.roles.corsace.verified, config.discord.roles.corsace.streamAnnouncements],
                    });
                }
            } catch (err) {
                console.log("An error occurred in adding a user to the server / changing their nickname: " + err);
            }

            ctx.login(user);
            const redirect = ctx.cookies.get("redirect");
            ctx.cookies.set("redirect", "");
            ctx.redirect(redirect ?? "back");
        } else {
            const redirect = ctx.cookies.get("redirect");
            ctx.cookies.set("redirect", "");
            ctx.redirect(redirect ?? "back");
            return;
        }
    })(ctx, next);
});
Example #23
Source File: discord.ts    From Corsace with MIT License 5 votes vote down vote up
discordRouter.get("/", redirectToMainDomain, async (ctx: ParameterizedContext<any>, next) => {
    const baseURL = ctx.query.site ? (config[ctx.query.site] ? config[ctx.query.site].publicUrl : config.corsace.publicUrl) : "";
    const params = ctx.query.redirect ?? "";
    const redirectURL = baseURL + params ?? "back";
    ctx.cookies.set("redirect", redirectURL, { overwrite: true });
    await next();
}, passport.authenticate("discord", { scope: ["identify", "guilds.join"] }));
Example #24
Source File: osu.ts    From Corsace with MIT License 4 votes vote down vote up
osuRouter.get("/callback", async (ctx: ParameterizedContext<any>, next) => {
    return await passport.authenticate("oauth2", { scope: ["identify", "public", "friends.read"], failureRedirect: "/" }, async (err, user) => {
        if (user) {
            await user.save();
            ctx.login(user);
            await next();
        } else {
            const redirect = ctx.cookies.get("redirect");
            ctx.cookies.set("redirect", "");
            ctx.redirect(redirect ?? "back");
            return;
        }
    })(ctx, next);
}, async (ctx, next) => {
    try {
        // api v2 data
        const res = await Axios.get("https://osu.ppy.sh/api/v2/me", {
            headers: {
                Authorization: `Bearer ${ctx.state.user.osu.accessToken}`,
            },
        });
        const data = res.data;

        // Username changes
        const usernames: string[] = data.previous_usernames;
        for (const name of usernames) {
            let nameChange = await UsernameChange.findOne({ name, user: ctx.state.user });
            if (!nameChange) {
                nameChange = new UsernameChange;
                nameChange.name = name;
                nameChange.user = ctx.state.user;
                await nameChange.save();
            }
        }

        // Check if current username is a previous username or not
        const currentName = await UsernameChange.findOne({
            name: ctx.state.user.osu.username,
            user: ctx.state.user,
        });
        if (currentName)
            await currentName.remove();

        // Check if BN/NAT/DEV/SPT/PPY
        if (data.groups.some(group => [11, 22, 33, 28, 32, 7, 31].some(num => group.id === num))) {
            let eligibleModes: string[] = [];
            if (data.groups.some(group => [11, 22, 33].some(num => group.id === num))) // DEV, SPT, PPY groups
                eligibleModes = ["standard", "taiko", "fruits", "mania"];
            else {
                for (const group of data.groups) { // BN, NAT groups
                    if (![28, 32, 7, 31].some(num => group.id === num))
                        continue;
                    if (group.id === 31 && group.playmodes.length === 0) {
                        eligibleModes.push(data.playmode);
                    } else 
                        eligibleModes.push(...group.playmodes);
                }
                eligibleModes = eligibleModes.map(mode => mode === "osu" ? "standard" : mode);
            }

            for (let year = 2007; year <= (new Date).getUTCFullYear(); year++) {
                let eligibility = await MCAEligibility.findOne({ relations: ["user"], where: { year: year, user: ctx.state.user }});
                if (!eligibility) {
                    eligibility = new MCAEligibility();
                    eligibility.year = year;
                    eligibility.user = ctx.state.user;
                }
                for (const eligibleMode of eligibleModes) {
                    if (!eligibility[eligibleMode]) {
                        eligibility[eligibleMode] = true;
                        eligibility.storyboard = true;
                    }
                }
                
                await eligibility.save();
                if (ctx.state.user.mcaEligibility) {
                    const i = ctx.state.user.mcaEligibility.findIndex((e: MCAEligibility) => e.year === year);
                    if (i === -1)
                        ctx.state.user.mcaEligibility.push(eligibility);
                    else
                        ctx.state.user.mcaEligibility[i] = eligibility;
                } else
                    ctx.state.user.mcaEligibility = [ eligibility ];
            }
        }

        await next();
    } catch (e) {
        if (e) {
            ctx.status = 500;
            console.error(e);
            ctx.body = { error: e };
        } else {
            throw e;
        }
    }
}, async ctx => {
    try {
        // MCA data
        const beatmaps = (await Axios.get(`https://osu.ppy.sh/api/get_beatmaps?k=${config.osu.v1.apiKey}&u=${ctx.state.user.osu.userID}`)).data;
        if (beatmaps.length != 0) {
            for (const beatmap of beatmaps) {
                if (!beatmap.version.includes("'") && (beatmap.approved == 2 || beatmap.approved == 1)) {
                    const date = new Date(beatmap.approved_date);
                    const year = date.getUTCFullYear();
                    let eligibility = await MCAEligibility.findOne({ relations: ["user"], where: { year: year, user: ctx.state.user }});
                    if (!eligibility) {
                        eligibility = new MCAEligibility();
                        eligibility.year = year;
                        eligibility.user = ctx.state.user;
                    }
                    
                    if (!eligibility[modes[beatmap.mode]]) {
                        eligibility[modes[beatmap.mode]] = true;
                        eligibility.storyboard = true;
                        await eligibility.save();
                        const i = ctx.state.user.mcaEligibility.findIndex((e: MCAEligibility) => e.year === year);
                        if (i === -1)
                            ctx.state.user.mcaEligibility.push(eligibility);
                        else
                            ctx.state.user.mcaEligibility[i] = eligibility;
                    }
                }
            }
        }
        const redirect = ctx.cookies.get("redirect");
        ctx.cookies.set("redirect", "");
        ctx.redirect(redirect ?? "back");
    } catch (e) {
        if (e) {
            ctx.status = 500;
            console.error(e);
            ctx.body = { error: e };
        } else {
            throw e;
        }
    }
});
Example #25
Source File: stageSearch.ts    From Corsace with MIT License 4 votes vote down vote up
export default function stageSearch (stage: "nominating" | "voting", initialCall: (ctx: ParameterizedContext, category: Category) => Promise<Vote[] | Nomination[]>) {
    return async (ctx: ParameterizedContext) => {
        if (!ctx.query.category)
            return ctx.body = {
                error: "Missing category ID!",
            };

        // Make sure user is eligible to nominate in this mode
        const modeString: string = parseQueryParam(ctx.query.mode) || "standard";
        const modeId = ModeDivisionType[modeString];
        if (!isEligibleFor(ctx.state.user, modeId, ctx.state.year))
            return ctx.body = { error: "Not eligible for this mode!" };

        let list: BeatmapInfo[] | BeatmapsetInfo[] | UserChoiceInfo[] = [];
        let setList: BeatmapsetInfo[] = [];
        let mapList: BeatmapInfo[] = [];
        let userList: UserChoiceInfo[] = [];
        const favIDs: number[] = [];
        const playedIDs: number[] = [];

        const category = await Category
            .createQueryBuilder("category")
            .innerJoinAndSelect("category.mca", "mca")
            .where("category.ID = :id", { id: ctx.query.category })
            .andWhere("mca.year = :year", { year: ctx.state.year })
            .getOneOrFail();
    
        
        // Check if this is the initial call, add currently nominated beatmaps/users at the top of the list
        const skip = parseInt(parseQueryParam(ctx.query.skip) || "") || 0;
        if (skip === 0) {
            let objects = await initialCall(ctx, category) as Vote[]; // doesnt really matter the type in this case
            objects = objects.filter(o => o.category.ID === category.ID);

            if (category.type == CategoryType.Beatmapsets && ctx.state.year < 2021)
                setList = objects.map(o => o.beatmapset?.getInfo(true) as BeatmapsetInfo);  
            else if (category.type == CategoryType.Beatmapsets && ctx.state.year >= 2021)
                mapList = objects.map(o => o.beatmap?.getInfo(true) as BeatmapInfo);
            else if (category.type == CategoryType.Users)
                userList = objects.map(o => o.user?.getCondensedInfo(true) as UserChoiceInfo);
        }
        
        if ((ctx.query.favourites === "true" || ctx.query.played === "true") && category.type == CategoryType.Beatmapsets) {
            const accessToken: string = await ctx.state.user.getAccessToken("osu");
            if (ctx.query.favourites === "true") { // Fav filter
                let offset = 0;
                for (;;) {
                    const res = await Axios.get(`https://osu.ppy.sh/api/v2/users/${ctx.state.user.osu.userID}/beatmapsets/favourite?limit=51&offset=${offset}`, {
                        headers: {
                            Authorization: `Bearer ${accessToken}`,
                        },
                    });
                    const sets = res.data.map(set => set.id);

                    favIDs.push(...sets);

                    if (sets.length < 51) break;

                    offset += sets.length;
                }
            }

            if (ctx.query.played === "true") { // Played filter
                let approvedDate = "";
                let _id = "";
                for (;;) {
                    let url = `https://osu.ppy.sh/api/v2/beatmapsets/search?played=played&q=ranked%3D${ctx.state.year}`;
                    if (approvedDate) url += `&cursor%5Bapproved_date%5D=${approvedDate}&cursor%5B_id%5D=${_id}`;
                    const res = await Axios.get(url, {
                        headers: {
                            Authorization: `Bearer ${accessToken}`,
                        },
                    });

                    if (!approvedDate && res.data.beatmapsets.length === 0) break;

                    const sets = res.data.beatmapsets.map(set => set.id);

                    playedIDs.push(...sets);

                    if (sets.length < 50) break;

                    approvedDate = res.data.cursor.approved_date;
                    _id = res.data.cursor._id;
                }
            }

        }

        const order = parseQueryParam(ctx.query.order);
        if (order !== undefined && order !== "ASC" && order !== "DESC")
            return ctx.body = {
                error: "order must be undefined, ASC or DESC",
            };

        let count = 0;
        const query: StageQuery = {
            category: category.ID,
            skip,
            option: parseQueryParam(ctx.query.option) || "",
            order,
            text: parseQueryParam(ctx.query.text) || "",
            favourites: favIDs,
            played: playedIDs,
        };
    
        if (category.type == CategoryType.Beatmapsets && ctx.state.year < 2021) { // Search for beatmapsets
            const [beatmaps, totalCount] = await Beatmapset.search(ctx.state.year, modeId, stage, category, query);
            
            setList.push(...beatmaps.map(map => map.getInfo()));
            list = setList;
            count = totalCount;
        } else if (category.type == CategoryType.Beatmapsets && ctx.state.year >= 2021) { // Search for beatmaps
            const [beatmaps, totalCount] = await Beatmap.search(ctx.state.year, modeId, stage, category, query);
            
            mapList.push(...beatmaps.map(map => map.getInfo()));
            list = mapList;
            count = totalCount;
        } else if (category.type == CategoryType.Users) { // Search for users
            const [users, totalCount] = await User.search(ctx.state.year, modeString, stage, category, query);
            
            userList.push(...users.map(user => user.getCondensedInfo()));
            list = userList;
            count = totalCount;
        } else
            return ctx.body = { error: "Invalid type parameter. Only 'beatmapsets' or 'users' are allowed."};
    
        ctx.body = {
            list,
            count,
        };
    };
}