@prisma/client#Role TypeScript Examples

The following examples show how to use @prisma/client#Role. 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: test.tsx    From frames with Mozilla Public License 2.0 6 votes vote down vote up
export async function getServerSideProps(context: GetServerSidePropsContext) {
    const MiddleWare = await import("../server/classes/middleware").then(m => m.default);
    const Media = await import("../server/classes/media").then(m => m.default);
    const trendingData = await new Media().getTrending();

    const data = trendingData.map(e => {
        const {id, backdrop, type, trailer, logo, name, overview} = e;
        return {id, backdrop, type, trailer, logo, name, overview}
    }).filter(e => e.logo !== null && e.type === MediaType.MOVIE).slice(0, 10) as Banner[];

    const pop = data.pop();
    const banner = [pop, ...data];
    const middleware = new MiddleWare();

    const {context: role} = await middleware.confirmContent<CookiePayload>(context.req.cookies, 'frames-cookie') || {
        email: 'unknown', context: Role.GUEST, session: 'unknown', validUntil: 0,
    };

    if (role !== Role.ADMIN) return {
        notFound: true
    }

    return {
        props: {
            banner
        }
    }
}
Example #2
Source File: auth.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc creates a user from their OAUTH2 credentials
     * @param email - email of the user
     * @param password - password of the user
     * @param authKey - auth key of the user
     */
    public async oauthHandler(email: string, password: string, authKey: string): Promise<AuthInterface> {
        let response = await this.authenticateUser(email, `${password}`);
        if (response.error && response.error === 'No such user exists')
            response = await this.register(email, `${password}`, authKey, Role.OAUTH);

        return response;
    }
Example #3
Source File: auth.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc creates the admin account and the guest accounts if they do not exist
     */
    public async createAccounts() {
        let password = this.generateKey(4, 5);
        password = await bcrypt.hash(password, 10);
        await this.prisma.user.upsert({
            create: {confirmedEmail: true, password, email: '[email protected]', role: Role.GUEST, userId: this.createUUID()},
            update: {},
            where: {email: '[email protected]'}
        });
        await this.prisma.user.upsert({
            where: {email: 'frames AI'},
            create: {confirmedEmail: true, password, email: 'frames AI', role: Role.ADMIN, userId: this.createUUID()},
            update: {}
        });
        if (this.regrouped.user)
            await this.prisma.user.upsert({
                create: {
                    confirmedEmail: true,
                    password: await bcrypt.hash(this.regrouped.user.admin_pass, 10),
                    email: this.regrouped.user.admin_mail,
                    role: Role.ADMIN,
                    userId: this.createUUID()
                },
                update: {},
                where: {email: this.regrouped.user.admin_mail}
            });
    }
Example #4
Source File: Account.tsx    From frames with Mozilla Public License 2.0 6 votes vote down vote up
export default function Account() {
    const {user} = useUser();
    const setAccountContext = useSetRecoilState(SideMenu)

    return (
        <div className={styles['user-account']} onMouseEnter={() => {
            if (user)
                setAccountContext(1)
        }} onMouseLeave={() => {
            setTimeout(() => {
                setAccountContext(0);
            }, 400)
        }}>
            <button className={styles["account-image"]} onClick={() => setAccountContext(val => val !== 0 ? 0: 1)}>
                <svg viewBox="0 0 512 512">
                    <circle className={styles['ac-circle']} cx="256" cy="256" r="256"/>
                    <path style={user && user.role !== Role.GUEST ? {fill: "#3cab66"} : {fill: '#c4c362'}}
                          id="ac-path" d="M442.272,405.696c-11.136-8.8-24.704-15.136-39.424-18.208l-70.176-14.08
                            c-7.36-1.408-12.672-8-12.672-15.68v-16.096c4.512-6.336,8.768-14.752,13.216-23.552c3.456-6.816,8.672-17.088,11.264-19.744
                            c14.208-14.272,27.936-30.304,32.192-50.976c3.968-19.392,0.064-29.568-4.512-37.76c0-20.448-0.64-46.048-5.472-64.672
                            c-0.576-25.216-5.152-39.392-16.672-51.808c-8.128-8.8-20.096-10.848-29.728-12.48c-3.776-0.64-8.992-1.536-10.912-2.56
                            c-17.056-9.216-33.92-13.728-54.048-14.08c-42.144,1.728-93.952,28.544-111.296,76.352c-5.376,14.56-4.832,38.464-4.384,57.664
                            l-0.416,11.552c-4.128,8.064-8.192,18.304-4.192,37.76c4.224,20.704,17.952,36.768,32.416,51.232
                            c2.368,2.432,7.712,12.8,11.232,19.648c4.512,8.768,8.8,17.152,13.312,23.456v16.096c0,7.648-5.344,14.24-12.736,15.68l-70.24,14.08
                            c-14.624,3.104-28.192,9.376-39.296,18.176c-3.456,2.784-5.632,6.848-5.984,11.264s1.12,8.736,4.096,12.032
                            C115.648,481.728,184.224,512,256,512s140.384-30.24,188.16-83.008c2.976-3.296,4.48-7.648,4.096-12.064
                            C447.904,412.512,445.728,408.448,442.272,405.696z"/>
                </svg>
            </button>
        </div>
    )
}
Example #5
Source File: Loader.tsx    From frames with Mozilla Public License 2.0 6 votes vote down vote up
export function BeforeExit() {
    const {user, signOut} = useUser();
    const {disconnect} = useGroupWatch();
    const {disconnect: castDisconnect} = useCast();
    useWindowListener('beforeunload', () => {
        disconnect();
        castDisconnect();
        user?.role === Role.GUEST && signOut();
    })

    useWindowListener('dragstart', (ev) => {
        ev.preventDefault();
        return false;
    })

    useEventListener('contextmenu', (ev) => {
        ev.preventDefault();
    })

    return null;
}
Example #6
Source File: _middleware.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
export default async function (request: NextRequest) {
    const userToken = await middleware.confirmContent<CookiePayload>(request.cookies,'frames-cookie') || {email: 'unknown', context: Role.GUEST, session: 'unknown', validUntil: 0, userId: 'unknown'};
    const url = request.nextUrl.clone();

    if (url.pathname === '/api/streamVideo' && url.searchParams.has('auth'))
        return await middleware.streamFile(url.searchParams.get('auth')!, request.headers.get('range')!);

    return NextResponse.next();
}
Example #7
Source File: listEditors.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc gets the details of a specific media related to a user in the database
     * @param mediaId - the id of the media to query the database for
     * @param userId - the id of the user to query the database for
     */
    public async getSpecificMediaInfo(mediaId: number, userId: string): Promise<SpringMedUserSpecifics | null> {
        const media = await this.prisma.media.findUnique({where: {id: mediaId}});
        const user = await this.prisma.user.findUnique({
            where: {userId},
            include: {lists: true, ratings: true, watched: true}
        });

        if (media && user) {
            const myList = user.lists.some(item => item.mediaId === mediaId);
            let rating = ((user.ratings.find(item => item.mediaId === mediaId)?.rate || 0) * 10).toFixed(0);
            rating = rating === '0' ? '5%' : rating + '%';

            const seen = await this.mediaClass.checkIfSeen(mediaId, userId);

            const canEdit = user.role === Role.ADMIN;
            const download = canEdit && media.type === MediaType.SHOW;
            const favorite = false;

            return {seen, myList, rating, download, favorite, canEdit};
        }

        return null;
    }
Example #8
Source File: modify.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc confirms the user is an admin
     * @param userId - the user identifier
     * @private
     */
    public async userIsAdmin(userId: string) {
        const user = await this.prisma.user.findUnique({
            where: {userId}
        });

        return user?.role === Role.ADMIN;
    }
Example #9
Source File: auth.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc attempts to modify a user's details with the given credentials
     * @param email - email of the user
     * @param password - password of the user
     * @param userId - userId of the user
     */
    public async modifyUser(email: string, password: string, userId: string) {
        password = await bcrypt.hash(password, 10);
        const user = await this.prisma.user.findUnique({where: {userId}});
        if (user) {
            if (user.role !== Role.OAUTH) {
                await this.clearSession(userId, true);
                await this.prisma.user.update({
                    data: {
                        email, password
                    }, where: {userId}
                })
            }
        }
    }
Example #10
Source File: auth.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc confirms that session /Session exists if account is guest, the account is deleted
     * @param session - session to check
     */
    public async validateSession(session: string): Promise<AuthInterface> {
        let result = await this.prisma.session.findFirst({where: {session}, include: {user: true}});
        if (result) {
            if (result.user.role === Role.GUEST) {
                try {
                    await this.prisma.user.delete({where: {userId: result.userId}});
                } catch (e) {
                    console.log(e);
                }

                return {error: 'guest session has expired'}
            }

            return result.valid > new Date() ? {
                response: 'valid',
                payLoad: {
                    session,
                    validUntil: new Date(result.valid).getTime(),
                    context: result.user.role,
                    email: result.user.email,
                    notificationChannel: result.user.notificationChannel
                }
            } : {error: 'app id has expired'};
        }

        return {error: 'invalid app id provided'};
    }
Example #11
Source File: playback.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc adds a file to the download queue if the auth token is valid and the auth file exists
     * @param auth - the auth location of the file
     * @param authKey - the auth token to be validated
     * @param userId - the user's identifier
     */
    public async addFileToDownload(auth: string, authKey: string, userId: string): Promise<string | null> {
        const user = new User();
        const file = await this.prisma.view.findFirst({where: {auth}, select: {video: true}});
        const userFile = await this.prisma.user.findUnique({where: {userId}});
        const valid = await user.validateAuthKey(authKey, userFile?.role || Role.USER);
        if (valid === 0 && file && userFile) {
            await user.utiliseAuthKey(authKey, userId, UseCase.DOWNLOAD, auth);
            const location = this.createUUID();
            await this.prisma.download.create({
                data: {
                    location, auth, userId
                }
            });
            return location;
        }

        return null;
    }
Example #12
Source File: auth.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc deletes a specific session for a user
     * @param session - session to be deleted
     */
    public async clearSingleSession(session: string) {
        const state = await this.prisma.session.findUnique({where: {session}, include: {user: true}});
        if (state) {
            try {
                if (state.user.role === Role.GUEST)
                    await this.prisma.user.delete({where: {userId: state.userId}});
                else
                    await this.prisma.session.delete({where: {session}});
            } catch (e) {
                console.log(e)
            }
        }
    }
Example #13
Source File: navbar.tsx    From frames with Mozilla Public License 2.0 6 votes vote down vote up
function Account() {
    const {user} = useUser();
    const setAccountContext = useSetRecoilState(SideMenu);
    const count = useRecoilValue(notificationCount);

    return (
        <div className={styles['user-account']} onMouseEnter={() => {
            if (user)
                setAccountContext(1)
        }} onMouseLeave={() => {
            setTimeout(() => {
                setAccountContext(0);
            }, 400)
        }}>
            <button className={styles["account-image"]} onClick={() => setAccountContext(val => val !== 0 ? 0 : 1)}>
                <svg viewBox="0 0 512 512">
                    <circle className={styles['ac-circle']} cx="256" cy="256" r="256"/>
                    <path
                        style={user ? user.role !== Role.GUEST ? {fill: "#3cab66"} : {fill: '#c4c362'} : {fill: "#f54e4e"}}
                        d="M442.272,405.696c-11.136-8.8-24.704-15.136-39.424-18.208l-70.176-14.08
                        c-7.36-1.408-12.672-8-12.672-15.68v-16.096c4.512-6.336,8.768-14.752,13.216-23.552c3.456-6.816,8.672-17.088,11.264-19.744
                        c14.208-14.272,27.936-30.304,32.192-50.976c3.968-19.392,0.064-29.568-4.512-37.76c0-20.448-0.64-46.048-5.472-64.672
                        c-0.576-25.216-5.152-39.392-16.672-51.808c-8.128-8.8-20.096-10.848-29.728-12.48c-3.776-0.64-8.992-1.536-10.912-2.56
                        c-17.056-9.216-33.92-13.728-54.048-14.08c-42.144,1.728-93.952,28.544-111.296,76.352c-5.376,14.56-4.832,38.464-4.384,57.664
                        l-0.416,11.552c-4.128,8.064-8.192,18.304-4.192,37.76c4.224,20.704,17.952,36.768,32.416,51.232
                        c2.368,2.432,7.712,12.8,11.232,19.648c4.512,8.768,8.8,17.152,13.312,23.456v16.096c0,7.648-5.344,14.24-12.736,15.68l-70.24,14.08
                        c-14.624,3.104-28.192,9.376-39.296,18.176c-3.456,2.784-5.632,6.848-5.984,11.264s1.12,8.736,4.096,12.032
                        C115.648,481.728,184.224,512,256,512s140.384-30.24,188.16-83.008c2.976-3.296,4.48-7.648,4.096-12.064
                        C447.904,412.512,445.728,408.448,442.272,405.696z"/>
                </svg>
            </button>
            {count ? <div className={styles.notification}>{count}</div>: null}
        </div>
    )
}
Example #14
Source File: Loader.tsx    From frames with Mozilla Public License 2.0 6 votes vote down vote up
export function BeforeExit() {
    const {user, signOut} = useUser();
    const {disconnect} = useCast();
    useWindowListener('beforeunload', () => {
        disconnect();
        user?.role === Role.GUEST && signOut();
    })

    useWindowListener('dragstart', (ev) => {
        ev.preventDefault();
        return false;
    })

    return null;
}
Example #15
Source File: auth.ts    From frames with Mozilla Public License 2.0 6 votes vote down vote up
/**
     * @desc checks if the auth key is valid or even exists
     * @param authKey - auth key to be checked
     * @param context - context of the request
     */
    public async validateAuthKey(authKey: string, context: Role): Promise<number> {
        let value = -1;
        if (authKey === 'homeBase' && (context === Role.ADMIN || context === Role.GUEST))
            value = 0;

        const authFile = await this.prisma.auth.findUnique({where: {authKey}});
        if (authFile)
            value = authFile.access;

        return value;
    }
Example #16
Source File: auth.ts    From frames with Mozilla Public License 2.0 5 votes vote down vote up
/**
     * @desc creates a new user with the given details
     * @param email - email of the user
     * @param password - password of the user
     * @param authKey - auth key of the user
     * @param role - role of the user
     * @returns Promise<AuthInterface> auth object on with either error or response on success
     */
    public async register(email: string, password: string, authKey: string, role?: Role): Promise<AuthInterface> {
        role = role || Role.USER;
        const confirmedEmail = role === Role.OAUTH || role === Role.GUEST;
        password = await bcrypt.hash(password, 10);
        const notificationChannel = this.generateKey(13, 7);
        let userId = this.createUUID();

        let user = await this.prisma.user.findFirst({where:{email}});

        if (user)
            return {error: 'this email already exists'};

        const validAuth = await this.validateAuthKey(authKey, role);
        if (validAuth !== 0) {
            const error = validAuth === -1 ? 'invalid auth key' : 'this auth key has already been used';
            return {error};
        }

        const userRes = await this.prisma.user.create({
            data: {email, password, userId, role, confirmedEmail, notificationChannel}
        });

        await this.utiliseAuthKey(authKey, userId, UseCase.SIGNUP);
        return !confirmedEmail ? {error: 'Please check your email for a verification link'}: {
            response: 'User created successfully',
            payLoad: {
                email: userRes.email,
                context: userRes.role,
                notificationChannel: userRes.notificationChannel,
                ...await this.generateSession(userRes.userId)
            }
        };
    }
Example #17
Source File: info.tsx    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export async function getServerSideProps(ctx: GetServerSidePropsContext) {
    let mediaId: number;
    const User = await import("../server/classes/auth").then(m => m.default);
    const Media = await import("../server/classes/media").then(m => m.default);
    const MiddleWare = await import("../server/classes/middleware").then(m => m.default);
    const user = new User();
    const media = new Media();
    const middleware = new MiddleWare();

    const data = await middleware.confirmContent<CookiePayload>(ctx.req.cookies, 'frames-cookie') || {
        email: 'unknown',
        context: Role.GUEST,
        session: 'unknown',
        validUntil: 0,
    };

    const presentUser = await user.getUserFromSession(data.session);
    const userId = presentUser?.userId || 'unknown';
    const pathname = ctx.query;

    if (pathname.hasOwnProperty('mediaId'))
        mediaId = +(pathname.mediaId)!;

    else {
        const type = pathname.hasOwnProperty('movie') ? MediaType.MOVIE : MediaType.SHOW;
        const data = type === 'MOVIE' ? pathname.movie : pathname.show;
        let value = Array.isArray(data) ? data[0] : data;
        const result = middleware.convertUrl(value as string);
        mediaId = await media.findMedia(result, type);
    }

    const info = await media.getMedia(mediaId, userId);
    if (info) {
        const metaTags: MetaTags = {
            link: '/' + (info.type === MediaType.MOVIE ? 'movie' : 'show') + '=' + info.name.replace(/\s/g, '+').replace(/\//, '!!'),
            poster: info.poster,
            overview: info.overview,
            name: info.name
        }

        return {props: {info, metaTags}};
    }

    return {
        notFound: true
    }
}
Example #18
Source File: _middleware.ts    From frames with Mozilla Public License 2.0 5 votes vote down vote up
verifyAccess = async function (request: NextRequest, response: NextResponse) {
    const userToken = await middleware.confirmContent<CookiePayload>(request.cookies, 'frames-cookie') || {email: 'unknown', context: Role.GUEST, session: 'unknown', validUntil: 0, userId: 'unknown'};
    const valid = Date.now() < userToken.validUntil;
    const path = request.nextUrl.pathname;
    const extension = getExtension(path);
    const isSEOBot = middleware.detectSEOBot(request);
    const url = request.nextUrl.clone();
    url.pathname = '/auth';

    if (isSEOBot) {
        if (extension !== 'unknown')
            return response;

        const html = await middleware.createHTML(path);
        return new Response(html, {
            headers: {
                "content-type": "text/html;charset=UTF-8",
            },
        })
    }

    if (path === '/midIn' || path === '/getApiKey') {
        const {email, context, session} = userToken;
        const res = path === '/getApiKey' ? await middleware.getApiKey(): !valid ? {error: 'access unauthorised'} : {
            context: {
                email,
                session,
                role: context
            }
        };

        return new Response(JSON.stringify(res), {
            status: 200,
            headers: {
                'Content-Type': 'application/json',
            },
        })

    } else if (path === '/midOut')
        return NextResponse.redirect(url).cookie('frames-cookie', 'null', {
            maxAge: 0,
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production',
            sameSite: 'strict',
            path: '/',
        });

    else if (extension !== 'unknown')
        return response;

    else if (!valid && !/\/api\/(auth|stream)/.test(path) && !/\/frame=|\/auth/.test(path))
        return NextResponse.redirect(url);

    else if (valid && path === '/auth' ) {
        if (request.redirect ===  'follow')
            return response;

        url.pathname = '/';
        return NextResponse.redirect(url);
    }

    return response;
}
Example #19
Source File: auth.ts    From frames with Mozilla Public License 2.0 5 votes vote down vote up
/**
     * @desc verifies the role of the provided user
     * @param userId - user id to be verified
     */
    public async validateUser(userId: string): Promise<boolean> {
        const user = await this.prisma.user.findFirst({where: {userId}});
        return user ? user.role === Role.ADMIN : false;
    }
Example #20
Source File: customHooks.ts    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export function useAuth() {
    const {user, confirmAuthKey} = useUser();
    const [lAuth, setLAuth] = useState(false);
    const [valid, setValid] = useState(false);
    const [auth, setAuth] = useRecoilState(AuthKeyAtom);
    const {authError} = useRecoilValue(AuthErrors);
    const {error} = useRecoilValue(AuthContextHandler);
    const setError = useSetRecoilState(AuthContextErrorAtom);

    const confirmKey = async () => {
        const res = await confirmAuthKey(auth);
        if (res !== 0) {
            const error = res === -1 ? 'invalid auth key': 'this auth key has already been used';
            setError(error);
            setLAuth(true);

        } else {
            setValid(true);
            setError(null);
            setLAuth(false);
        }
    }

    const manageAuth = async (auth: string) => {
        if (auth.length === 23)
            await confirmKey();

        else if (auth === 'homeBase') {
            if (user?.role === Role.ADMIN) {
                setError(null);
                setLAuth(false);
                setValid(true);

            } else {
                setError('invalid auth key')
                setLAuth(true);
                setValid(false);
            }
        }

        else {
            setError(null);
            setLAuth(false);
            setValid(false);
        }
    }

    useEffect(() => {
        manageAuth(auth);
    }, [auth])

    return {authError: authError || lAuth, auth, setAuth, valid, error}
}
Example #21
Source File: infoDetails.tsx    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export default function InfoDetails ({response, loadTrailer}: InfoType) {
    const trailer = useRecoilValue(infoTrailerContext);
    const dispatch = useSetRecoilState(EditMediaContext);
    const setInform = useSetRecoilState(InformDisplayContext);
    const {user} = useUser();

    const handleEdit = () => {
        const {id, name, type, backdrop, poster, logo} = response;
        const data: EditMedia = {
            media: {
                id, name, type,
                backdrop, poster, logo
            }
        }
        dispatch(data);
    }

    const handleDownload = async () => {
        await fetch(`/api/update/epiDown?id=${response.id}`);
        setInform({
            type: "alert",
            heading: 'Library scan begun',
            message: 'Frames would begin checking for new episodes of ' + response.name
        })
    }

    return (
        <>
            <div className={info.infoNaming}>
                {response.logo ? <img src={response.logo} alt={response.name}/> : <span className="infoLogo">{response.name}</span>}
            </div>
            <div className={info.infoButtons} style={response.type === 'MOVIE' ? response.myList ? {width: '44%'}: {width: '44%'}: {width: '58%'}}>
                <PlayButton id={response.id}/>
                <TrailerButton id={response.id} trailer={trailer} onClick={loadTrailer}/>
                <PLayList id={response.id} type={response.type}/>
                <Shuffle id={response.id} type={response.type}/>
                <MyList id={response.id} myList={response.myList}/>
                <Seen id={response.id} seen={response.seen}/>
                <GroupWatch id={response.id} type={response.type}/>
                {user?.role === Role.ADMIN ?
                    <>
                        <Template id={2} type={'edit'} name={'edit ' + response.name} onClick={handleEdit}/>
                        {response.download ? <Template id={2} type={'down'} name={'download more ' + response.name} onClick={handleDownload}/>: null}
                    </>
                    : null}
            </div>
            <div className={info.detailsHolder}>
                <div className={info.infoDetails}>
                    <div className={info.rating}>{response.rating}</div>
                    <span>-</span>
                    <div>{response.release}</div>
                    <span>-</span>
                    <div>{response.genre}</div>
                    <span>-</span>
                    <div>{response.runtime}</div>
                    <Rating {...{id: response.id, review: response.review, myRating: response.myRating}}/>
                </div>
            </div>
            <div className={info.infoOverview}>
                <p>{response.overview}</p>
            </div>
        </>
    )
}
Example #22
Source File: auth.ts    From frames with Mozilla Public License 2.0 5 votes vote down vote up
/**
     * @desc creates a guest user that in theory should be usable for one session
     * @param password - email of the user
     */
    public async createGuestUser(password: string) {
        const email = password + '@frames.local';
        return await this.register(email, password, 'homeBase', Role.GUEST);
    }
Example #23
Source File: userTools.tsx    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export function UserContextProvider({children}: { children: ReactNode }) {
    const base = useBase();
    const setUser = useSetRecoilState(UserContext);
    const setLoading = useSetRecoilState(Loading);
    const [apiKey, setApiKey] = useState('');

    const getUser = async () => {
        const data = await base.makeRequest<{apiKey: string, globalKey: string}>('/getApiKey', null);
        if (data) {
            setApiKey(data.apiKey);
            setLoading(prev => ({...prev, globalKey: data.globalKey}));
        }

        const res = await base.makeRequest<ServerResponse>('/midIn', {process: 'context'});
        if (res?.error) {
            setLoading(prev => ({...prev, loading: false}));
            setUser(null);
            return;

        } else if (res?.context?.role === Role.GUEST) {
            setUser(null);
            await fetch('/api/auth?action=logout');
            await fetch('midOut');
            setLoading(prev => ({...prev, loading: false}));

        } else {
            const username = res?.context?.email.split('@')[0] || '';
            setUser(res?.context ? {...res.context, username} : null);
            setLoading(prev => ({...prev, loading: false}));
        }

        const context = res?.context || {};
        const serverContext = await base.makeRequest<ServerResponse>('/api/auth', {
            ...context,
            process: 'context'
        }, 'POST');
        if (serverContext?.error) {
            setLoading(prev => ({...prev, loading: false}));
            setUser(null);
            return;
        } else {
            const username = serverContext?.context?.email.split('@')[0] || '';
            setUser(serverContext?.context ? {...serverContext.context, username} : null);
            setLoading(prev => ({...prev, loading: false}));
        }
    }

    useEffect(() => {
        getUser();
    }, []);

    return (
        <RealtimeConsumer apiKey={apiKey}>
            {children}
        </RealtimeConsumer>
    )
}
Example #24
Source File: userTools.tsx    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export function useAuth() {
    const {user, confirmAuthKey} = useUser();
    const [lAuth, setLAuth] = useState(false);
    const [valid, setValid] = useState(false);
    const [auth, setAuth] = useRecoilState(AuthKeyAtom);
    const {authError} = useRecoilValue(AuthErrors);
    const {error} = useRecoilValue(AuthContextHandler);
    const setError = useSetRecoilState(AuthContextErrorAtom);

    const confirmKey = async () => {
        const res = await confirmAuthKey(auth);
        if (res !== 0) {
            const error = res === -1 ? 'invalid auth key' : 'this auth key has already been used';
            setError(error);
            setLAuth(true);

        } else {
            setValid(true);
            setError(null);
            setLAuth(false);
        }
    }

    const manageAuth = async (auth: string) => {
        if (auth.length === 24)
            await confirmKey();

        else if (auth === 'homeBase') {
            if (user?.role === Role.ADMIN) {
                setError(null);
                setLAuth(false);
                setValid(true);

            } else {
                setError('invalid auth key')
                setLAuth(true);
                setValid(false);
            }
        } else {
            setError(null);
            setLAuth(false);
            setValid(false);
        }
    }

    useEffect(() => {
        manageAuth(auth);
    }, [auth])

    return {authError: authError || lAuth, auth, setAuth, valid, error}
}
Example #25
Source File: playback.ts    From frames with Mozilla Public License 2.0 5 votes vote down vote up
cleanUp = () => {
    const {user, signOut} = useUser();
    const response = useRecoilValue(framesVideoStateAtom);
    const fullscreenReset = useResetRecoilState(fullscreenAddressAtom);
    const framesVideoStateReset = useResetRecoilState(framesVideoStateAtom);
    const currentReset = useResetRecoilState(currentDuration);
    const framesReset = useResetRecoilState(framesPlayer);
    const framesPlayerStateReset = useResetRecoilState(framesPlayerStateAtom);
    const volumeFrameReset = useResetRecoilState(volumeFrameAtom);
    const displayReset = useResetRecoilState(displaySidesAtom);
    const shareAndDownloadReset = useResetRecoilState(shareAndDownloadAtom);
    const PipAndFullscreenReset = useResetRecoilState(PipAndFullscreenAtom);
    const SubtitlesAndUpNextReset = useResetRecoilState(SubtitlesAndUpNextAtom);
    const UpNextReset = useResetRecoilState(UpNextAtom);
    const HideImageReset = useResetRecoilState(HideImageAtom);
    const framesSubtitlesReset = useResetRecoilState(framesSubtitlesAtom);
    const SubtitlesSyncReset = useResetRecoilState(SubtitlesSyncAtom);
    const FramesPlayerErrorReset = useResetRecoilState(FramesPlayerErrorAtom);
    const CastEventReset = useResetRecoilState(CastEventAtom);
    const CastStateReset = useResetRecoilState(VideoStateAtom);
    const AirplayReset = useResetRecoilState(AirplayAtom);
    const alreadyStreamingReset = useResetRecoilState(AlreadyStreamingAtom);
    const {channel} = useGroupWatch();
    const {globalChannel} = useNotification();

    return  () => {
        channel.modifyPresenceState('online');
        globalChannel.modifyPresenceState('online');
        fetch('/api/stream/verifyStream?action=done');
        if (user?.role === Role.GUEST && response?.frame)
            signOut();

        fullscreenReset();
        framesVideoStateReset();
        currentReset();
        framesReset();
        framesPlayerStateReset();
        volumeFrameReset();
        displayReset();
        shareAndDownloadReset();
        PipAndFullscreenReset();
        SubtitlesAndUpNextReset();
        UpNextReset();
        HideImageReset();
        framesSubtitlesReset();
        SubtitlesSyncReset();
        FramesPlayerErrorReset();
        CastEventReset();
        CastStateReset();
        AirplayReset();
        alreadyStreamingReset();
    }
}
Example #26
Source File: navbar.tsx    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export function AccountInfo() {
    const count = useRecoilValue(notificationCount);
    const setSides = useSetRecoilState(SettingsSegmentContext);
    const accountContext = useRecoilValue(SideMenu);
    const [visible, setVisible] = useState(false);
    const router = useRouter();
    const {user, signOut} = useUser();
    const win = useRef<Window | null>(null);

    const handleClick = () => {
        win.current = window.open('https://www.paypal.com/paypalme/RoyOssai', '_blank');
    }

    const setSidesAndPush = async (step1: string, step2: string) => {
        setSides({step1, step2});
        router.asPath !== '/settings' && await router.push('/settings');
    }

    if (user)
        return (
            <div className={styles.holderContainer}
                 style={accountContext === 0 && !visible ? {opacity: "0", pointerEvents: 'none'} : {opacity: "1"}}
                 onMouseEnter={() => setVisible(true)} onMouseLeave={() => {
                setTimeout(() => {
                    setVisible(false);
                }, 200)
            }}>
                <div className={styles.text} onClick={() => setSidesAndPush('account', 'watch history')}>{user.role === Role.GUEST ? 'Guest: ': ''}{user.username || user.email}</div>
                <div className={styles.spacer}/>
                <div className={styles.text} onClick={() => setSidesAndPush('account', 'notifications')}>Notifications{count ? `: ${count}`: ''}</div>
                <div className={styles.text} onClick={() => setSidesAndPush('about', 'feedback')}>Make Suggestions</div>
                <div className={styles.text} onClick={handleClick}>Buy me coffee</div>
                <div className={styles.text} onClick={() => setSidesAndPush('about', 'privacy policy')}>Privacy & TOS</div>
                {user.role === Role.ADMIN ?
                    <>
                        <div className={styles.spacer}/>
                        <div className={styles.text} onClick={() => setSidesAndPush('manage', 'get contents')}>Manage contents</div>
                    </>
                : null}
                <div className={styles.spacer}/>
                <div className={styles.text} onClick={signOut}>log out</div>
            </div>
        )

    else return null;
}
Example #27
Source File: infoDetails.tsx    From frames with Mozilla Public License 2.0 5 votes vote down vote up
export default function InfoDetails({response, loadTrailer, trailer}: InfoType) {
    const infoUser = useRecoilValue(infoUserContext);
    const {getMedia} = useModify();
    const {downloadEpisodes} = useGetContext();
    const {user} = useUser();

    return (
        <>
            <div className={info.infoNaming}>
                {response.logo ? <img src={response.logo} alt={response.name}/> :
                    <span className="infoLogo">{response.name}</span>}
            </div>
            <div className={info.infoButtons}
                 style={response.type === 'MOVIE' ? infoUser?.myList ? {width: '44%'} : {width: '44%'} : {width: '58%'}}>
                <PlayButton id={response.id}/>
                <TrailerButton id={response.id} trailer={trailer} onClick={loadTrailer}/>
                <Shuffle id={response.id} type={response.type}/>
                <MyList id={response.id} myList={infoUser?.myList}/>
                <Seen id={response.id} seen={infoUser?.seen}/>
                <GroupWatch id={response.id} />
                <PLayList id={response.id} type={response.type}/>
                {infoUser === null && user?.role === Role.ADMIN || infoUser?.canEdit ?
                    <Template id={2} type={'edit'} name={'edit ' + response.name}
                              onClick={() => getMedia(response.id)}/> : null}
                {(infoUser === null && user?.role === Role.ADMIN && response.type === MediaType.SHOW) || infoUser?.download ?
                    <Template id={2} type={'down'} name={'download more episodes for ' + response.name}
                              onClick={() => downloadEpisodes(response.id, response.name)}/> : null}
            </div>
            <div className={info.detailsHolder}>
                <div className={info.infoDetails}>
                    <div className={info.rating}>{response.rating}</div>
                    <span>-</span>
                    <div>{response.release}</div>
                    <span>-</span>
                    <div>{response.genre}</div>
                    <span>-</span>
                    <div>{response.runtime}</div>
                    <Rating {...{id: response.id, review: response.vote_average, myRating: infoUser?.rating}}/>
                </div>
            </div>
            <div className={info.infoOverview}>
                <p>{response.overview}</p>
            </div>
        </>
    )
}
Example #28
Source File: playback.ts    From frames with Mozilla Public License 2.0 4 votes vote down vote up
/**
     * @desc Handle the creation of the play back information
     * @param video - The video object
     * @param userId - The user identifier
     * @param playlistId - The playlist video identifier
     * @param episode - The episode object
     * @param inform - The inform? variable
     */
    private async handlePlayBackCreation(video: (Video & { media: Med }), userId: string, playlistId: number | null, episode: Episode | null, inform: boolean): Promise<SpringLoad | null> {
        const {media, english, french, german} = video;
        let episodeName: string | null = null;
        let location = this.createUUID();

        let {overview, backdrop, poster, logo, name} = media;
        if (episode) {
            const episodeInfo = await this.mediaClass.getEpisode(episode.id);
            if (episodeInfo) {
                overview = episodeInfo.overview || overview;
                episodeName = episodeInfo.name;
            }
        }

        let subs = [];
        if (!english && !french && !german)
            subs = await this.scanner.getSub({...video, episode}, location);

        else {
            if (english)
                subs.push({
                    language: 'English',
                    url: '/api/stream/subtitles?auth=' + location + '&language=english',
                    label: 'English',
                    lang: 'en'
                });

            if (french)
                subs.push({
                    language: 'French',
                    url: '/api/stream/subtitles?auth=' + location + '&language=french',
                    label: 'Français',
                    lang: 'fr'
                });

            if (german)
                subs.push({
                    language: 'German',
                    url: '/api/stream/subtitles?auth=' + location + '&language=german',
                    label: 'Deutsch',
                    lang: 'de'
                });
        }

        const user = await this.prisma.user.findFirst({where: {userId}});
        if (user) {
            inform = user.inform ? inform : false;
            const obj = {
                inform,
                playlistId,
                videoId: video.id,
                episodeId: episode?.id,
                auth: location, userId,
                created: new Date(),
                updated: new Date(),
            };

            const watched = await this.prisma.watched.findUnique({where: {seenByUser: {userId, videoId: video.id}}});

            await this.prisma.view.upsert({
                where: {auth: location},
                update: obj,
                create: obj
            });

            return {
                playlistId,
                videoId: video.id,
                mediaId: media.id,
                episodeId: episode?.id || null,
                autoPlay: user.autoplay,
                playerId: this.createUUID(), frame: false,
                location, inform, overview, activeSub: user.defaultLang,
                logo, backdrop, name, poster, cdn: this.regrouped.user?.cdn || '/api/streamVideo?auth=',
                position: inform ? (watched?.position || 0) > 939 ? 0 : (watched?.position || 0) : 0,
                episodeName, subs, guest: user.role === Role.GUEST
            };
        }

        return null;
    }
Example #29
Source File: userTools.ts    From frames with Mozilla Public License 2.0 4 votes vote down vote up
export default function useUser(frames = false, confirm = false) {
    const [loading, setLoading] = useRecoilState(Loading);
    const setError = useSetRecoilState(AuthContextErrorAtom);
    const setPicker = useSetRecoilState(AuthPicker);
    const setFade = useSetRecoilState(AuthFade);
    const [user, setUser] = useRecoilState(UserContext);

    const confirmMail = async (user: string) => {
        let info: boolean = await pFetch({process: 'confirmEmail', email: user}, '/api/auth');
        setPicker(info);
        return info ? "password" : "create";
    }

    const confirmAuthKey = async (authKey: string) => {
        let info: number = await pFetch({process: 'confirmAuthKey', authKey}, '/api/auth');
        return info;
    }

    const signIn = async (user: string, pass: string) => {
        let data = {user, pass, process: 'logIn'};
        let res: ServerResponse = await pFetch(data, '/api/auth');
        if (res.error)
            setError(res.error);
        else if (res.context)
            setUser(res.context);
    }

    const signUp = async (user: string, pass: string, authKey: string) => {
        let data = {user, pass, authKey, process: 'create'};
        let res: ServerResponse = await pFetch(data, '/api/auth');
        if (res.error)
            setError(res.error);
        else if (res.context)
            setUser(res.context);
    }

    const signAsGuest = async () => {
        setFade(true);
        const data = {process: 'guestIn'};
        let res: ServerResponse = await pFetch(data, '/api/auth');
        if (res.error)
            setUser(null);
        else if (res.context)
            setUser(res.context);
    }

    const signOut = async () => {
        setUser(null);
        await fetch('/api/auth?action=logout');
    }

    const oauthAuth = async (user_name: string, oauthPass: number, email: string, authKey?: string) => {
        const user = {user: email, pass: `${oauthPass}`, username: user_name, authKey, process: 'OAUTH'};
        let res: ServerResponse = await pFetch(user, '/api/auth');
        if (res.error)
            setError(res.error);
        else if (res.context)
            setUser(res.context);
    }

    const confirmAuth = async () => {
        let res: ServerResponse = await pFetch({process: 'confirmAuth'}, '/api/auth');
        if (res.error)
            setError(res.error);
        else if (res.context)
            setUser(res.context);

        setLoading(false);
    }

    const getFrameUser = async () => {
        let res: ServerResponse = await pFetch({process: 'framedUser'}, '/api/auth');
        if (res.error)
            setError(res.error);
        else if (res.context)
            setUser(res.context);

        setLoading(false);
    }

    const generateAuthKey = async (): Promise<{ authKey?: string, error?: string }> => {
        if (user && user.role === Role.ADMIN) {
            const response: { authKey: string } | null = await pFetch({
                ...user,
                process: 'generateAuthKey'
            }, '/api/auth');
            if (response)
                return response;
        }

        return {error: 'You do not have permission to generate keys'};
    }

    const manageKeys = async () => {
        if (user && user.role === Role.ADMIN) {
            const response: ManageAuthKey[] | null = await pFetch({...user, process: 'manageKeys'}, '/api/auth');
            if (response)
                return {response};
        }

        return {error: 'You do not have permission this action'};
    }

    useLoadEffect(() => {
        if (loading && confirm) {
            if (frames)
                getFrameUser();

            else if (!user)
                confirmAuth();

            else
                setLoading(false);
        }
        return () => frames && user?.role === Role.GUEST && signOut();
    }, [user])

    return {
        user,
        loading,
        confirmMail,
        generateAuthKey,
        signAsGuest,
        signIn,
        signUp,
        oauthAuth,
        signOut,
        confirmAuthKey,
        manageKeys
    }
}