/**
Copyright 2021 Forestry.io Holdings, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/ import { ModalBuilder } from './AuthModal' ; import React , { useState } from 'react' ; import { TinaCMS , TinaProvider , MediaStore , BranchSwitcherPlugin , Branch , BranchDataProvider , useLocalStorage , } from '@tinacms/toolkit' ; import { Client , TinaIOConfig } from '../client' ; import { useTinaAuthRedirect } from './useTinaAuthRedirect' ; import { CreateClientProps , createClient } from '../utils' ; import { setEditing } from '@tinacms/sharedctx' ; type ModalNames = null | 'authenticate' ; function sleep ( ms ) { return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ; } export interface TinaCloudMediaStoreClass { new ( client ) : MediaStore ; } export interface TinaCloudAuthWallProps { cms ? : TinaCMS ; children : React . ReactNode ; loginScreen ? : React . ReactNode ; tinaioConfig ? : TinaIOConfig ; getModalActions ? : ( args : { closeModal : ( ) => void ; } ) => { name : string ; action : ( ) => Promise < void > ; primary : boolean ; } [ ] ; mediaStore ? : TinaCloudMediaStoreClass | ( ( ) => Promise < TinaCloudMediaStoreClass > ) ; } export const AuthWallInner = ( { children , cms , loginScreen , getModalActions , } ) => { const client = cms . api . tina ; const [ activeModal , setActiveModal ] = useState < ModalNames > ( null ) ; const [ showChildren , setShowChildren ] = useState < boolean > ( false ) ; React . useEffect ( ( ) => { client . isAuthenticated ( ) . then ( ( isAuthenticated ) => { if ( isAuthenticated ) { setShowChildren ( true ) ; cms . enable ( ) ; } else { sleep ( 500 ) . then ( ( ) => { setActiveModal ( 'authenticate' ) ; } ) ; } } ) ; } , [ ] ) ; const onAuthSuccess = async ( ) => { if ( await client . isAuthenticated ( ) ) { setShowChildren ( true ) ; setActiveModal ( null ) ; } else { throw new Error ( 'No access to repo' ) ; } } ; const otherModalActions = getModalActions ? getModalActions ( { closeModal : ( ) => { setActiveModal ( null ) ; } , } ) : [ ] ; return ( < > { activeModal === 'authenticate' && ( < ModalBuilder title = "Tina Cloud Authorization" message = "To save edits, Tina Cloud authorization is required. On save, changes will get commited using your account." close = { close } actions = { [ ... otherModalActions , { action : async ( ) => { setEditing ( false ) ; window . location . reload ( ) ; } , name : 'Close' , primary : false , } , { name : 'Continue to Tina Cloud' , action : async ( ) => { await client . authenticate ( ) ; onAuthSuccess ( ) ; } , primary : true , } , ] } />)} { showChildren ? children : loginScreen ? loginScreen : null } < />); } ; /**
 * Provides the ability to setup your CMS and media while also providing an authentication wall so Tina is not enabled without a valid user session.
 *
 * Note: this will not restrict access for local filesystem clients
 */ export const TinaCloudProvider = ( props ) => { const baseBranch = props . branch || 'main' ; const [ currentBranch , setCurrentBranch ] = useLocalStorage ( 'tinacms-current-branch' , baseBranch ) ; useTinaAuthRedirect ( ) ; const cms = React . useMemo ( ( ) => props . cms || new TinaCMS ( { enabled : true , sidebar : true , } ) , [ props . cms ] ) ; if ( ! cms . api . tina ) { cms . registerApi ( 'tina' , createClient ( props ) ) ; } const setupMedia = async ( ) => { if ( props . mediaStore ) { if ( props . mediaStore . prototype ?. persist ) { cms . media . store = new props . mediaStore ( cms . api . tina ) ; } else { const MediaClass = await props . mediaStore ( ) ; cms . media . store = new MediaClass ( cms . api . tina ) ; } } } ; const handleListBranches = async ( ) : Promise < Branch [ ] > => { const { owner , repo } = props ; const branches = await cms . api . tina . listBranches ( { owner , repo } ) ; if ( ! Array . isArray ( branches ) ) { return [ ] ; } return branches ; } ; const handleCreateBranch = async ( data ) => { const newBranch = await cms . api . tina . createBranch ( data ) ; return newBranch ; } ; setupMedia ( ) ; const [ branchingEnabled , setBranchingEnabled ] = React . useState ( ( ) => cms . flags . get ( 'branch-switcher' ) ) ; React . useEffect ( ( ) => { cms . events . subscribe ( 'flag:set' , ( { key , value } ) => { if ( key === 'branch-switcher' ) { setBranchingEnabled ( value ) ; } } ) ; } , [ cms . events ] ) ; React . useEffect ( ( ) => { let branchSwitcher ; if ( branchingEnabled ) { branchSwitcher = new BranchSwitcherPlugin ( { listBranches : handleListBranches , createBranch : handleCreateBranch , } ) ; cms . plugins . add ( branchSwitcher ) ; } return ( ) => { if ( branchingEnabled && branchSwitcher ) { cms . plugins . remove ( branchSwitcher ) ; } } ; } , [ branchingEnabled , props . branch ] ) ; React . useEffect ( ( ) => { if ( props . cmsCallback ) { props . cmsCallback ( cms ) ; } } , [ ] ) ; return ( < BranchDataProvider currentBranch = { currentBranch } setCurrentBranch = { ( b ) => { setCurrentBranch ( b ) ; } } > < TinaProvider cms = { cms } > < AuthWallInner { ... props } cms = { cms } / > < /TinaProvider> < /BranchDataProvider>); } ; deprecated export const TinaCloudAuthWall = TinaCloudProvider ;