Skip to content

Commit

Permalink
Merge branch 'main' into fix/hresp
Browse files Browse the repository at this point in the history
  • Loading branch information
autodidaddict authored Mar 8, 2024
2 parents 2d98c00 + ae134a0 commit a2c7c63
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 50 deletions.
4 changes: 4 additions & 0 deletions internal/globalservice/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ func (c *Client) Whoami() (*models.WhoamiResponse, error) {
if err != nil {
return nil, err
}
if apiResult.Code == 404 {
return nil, nil
}

if apiResult.Error != nil {
return nil, errors.New(*apiResult.Error)
}
Expand Down
18 changes: 11 additions & 7 deletions natster-io/public/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ get_version() {
command curl -L -s \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/synadia-labs/natster/releases/latest |
https://natster.io/dl/latest |
command jq -r '.name'
)
}
Expand Down Expand Up @@ -89,16 +89,20 @@ echo "
os=$(get_os)
arch=$(get_arch)
binary_version=$(get_version)
file_name="nex_${binary_version}_${os}_${arch}"
asset_uri="https://github.com/synadia-labs/natster/releases/download/${binary_version}/${file_name}"
# file_name="natster_${binary_version}_${os}_${arch}"
# asset_uri="https://github.com/synadia-labs/natster/releases/download/${binary_version}/${file_name}"
file_name="natster"
asset_uri="https://natster.io/dl/natster_${os}_${arch}/${file_name}"

downloadFolder="${TMPDIR:-/tmp}"
mkdir -p ${downloadFolder}
downloadFolder="${TMPDIR:-/tmp}/natster_installer"
executable_folder="${HOME}/.natster/bin"
downloaded_file="${downloadFolder}/natster"
executable_folder="/usr/local/bin"

mkdir -p ${downloadFolder}
mkdir -p ${executable_folder}

echo "[1/3] Download ${asset_uri} to ${downloadFolder}"
rm -f ${downloaded_file}
rm -f ${downloadedFolder}
curl --silent --fail --location --output "${downloaded_file}" "${asset_uri}"

echo "[2/3] Install natster to ${executable_folder}"
Expand Down
34 changes: 32 additions & 2 deletions natster-io/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ var static embed.FS
type Options struct {
servePort int
serveHost string

binDir string
logging bool
}

var (
Expand All @@ -37,6 +40,8 @@ func main() {
serve := natsterServer.Command("serve", "Serve webapp")
serve.Flag("host", "Host to serve on").StringVar(&Opts.serveHost)
serve.Flag("port", "Port to listen on").Default("8080").IntVar(&Opts.servePort)
serve.Flag("binDir", "Directory holding natster binaries").Default("/tmp/natster_binaries/").StringVar(&Opts.binDir)
serve.Flag("withLogging", "Logs web request").Default("false").UnNegatableBoolVar(&Opts.logging)
serve.Action(func(_ *fisk.ParseContext) error {
return RunServer()
})
Expand All @@ -45,13 +50,38 @@ func main() {
}

func RunServer() error {
muxer := http.NewServeMux()

info, err := os.Stat(Opts.binDir)
if err != nil {
fmt.Println("WARN no bin dir, not serving")
} else {
if info.IsDir() {
binServe := http.FileServer(http.Dir(Opts.binDir))
muxer.Handle("/dl/", http.StripPrefix("/dl", binServe))
} else {
fmt.Println("WARN user did not provide directory, not serving")
}
}

var staticFS = fs.FS(static)
htmlContent, err := fs.Sub(staticFS, "dist")
if err != nil {
log.Fatal(err)
}
fs := http.FileServer(http.FS(htmlContent))
muxer.Handle("/", http.FileServer(http.FS(htmlContent)))

fmt.Printf("Server started %s:%d\n", Opts.serveHost, Opts.servePort)
return http.ListenAndServe(fmt.Sprintf("%s:%d", Opts.serveHost, Opts.servePort), fs)
if Opts.logging {
return http.ListenAndServe(fmt.Sprintf("%s:%d", Opts.serveHost, Opts.servePort), logz(muxer))
} else {
return http.ListenAndServe(fmt.Sprintf("%s:%d", Opts.serveHost, Opts.servePort), muxer)
}
}

func logz(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Host: %s | Path: %s | Query: %s\n", r.Host, r.URL.Path, r.URL.RawQuery)
handler.ServeHTTP(w, r)
})
}
19 changes: 16 additions & 3 deletions natster-io/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,25 @@ import GettingStartedView from '../views/GettingStartedView.vue'
import AuthView from '../views/AuthView.vue'
import Library from '../components/Library.vue'

import { userStore } from '../stores/user'

function isAuthAndHasLocal(to) {
const { isAuthenticated } = useAuth0()
const uStore = userStore()

if (isAuthenticated && uStore.hasJWT && uStore.hasNkey) {
return { name: 'library' }
}

return true
}

const router = createRouter({
history: createWebHashHistory(),
routes: [
{ path: '/:code?', name: 'home', component: HomeView },
{ path: '/library', name: 'library', component: Library, beforeEnter: authGuard },
{ path: '/getting-started', name: 'gettingstarted', component: GettingStartedView }
{ path: '/:code?', name: 'home', component: HomeView, beforeEnter: [isAuthAndHasLocal] },
{ path: '/getting-started', name: 'gettingstarted', component: GettingStartedView, beforeEnter: [isAuthAndHasLocal] },
{ path: '/library', name: 'library', component: Library, beforeEnter: [isAuthAndHasLocal] }
]
})

Expand Down
6 changes: 6 additions & 0 deletions natster-io/src/stores/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ export const userStore = defineStore('user', {
}
},
getters: {
hasJWT(state) {
return state.jwt !== '' || localStorage.getItem('natster_jwt') !== null
},
hasNkey(state) {
return state.nkey !== '' || localStorage.getItem('natster_nkey') !== null
},
getLastSeen(state) {
return state.last_seen_ts
},
Expand Down
35 changes: 27 additions & 8 deletions natster-io/src/views/GettingStartedView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,23 @@
<div class="lg:max-w-lg">
<img :src="natsterImg" class="h-20" />
<p class="mt-6 text-xl leading-8 text-gray-700">
Natster is a secure peer-to-multipeer, decentralized media sharing platform</p>
Natster is a secure peer-to-multipeer, decentralized media sharing platform.</p>
</div>
</div>
</div>
<div class="-ml-12 -mt-12 p-12 lg:sticky lg:top-4 lg:col-start-2 lg:row-span-2 lg:row-start-1 lg:overflow-hidden">
<VCodeBlock :code="code" highlightjs lang="bash" theme="tokyo-night-light" copyTab />
<h2 class="lg:pt-15 pb-2 mt-16 text-2xl font-bold tracking-tight text-gray-900">Getting Started with Natster
</h2>
<VCodeBlock :code="code_init" highlightjs lang="bash" theme="tokyo-night-light" copyTab />
<br />
<h2 class="pb-2 mt-10 text-2xl font-bold tracking-tight text-gray-900">Create your first Natster share</h2>
<VCodeBlock :code="code_share" highlightjs lang="bash" theme="tokyo-night-light" copyTab />
</div>
<div
class="lg:col-span-2 lg:col-start-1 lg:row-start-2 lg:mx-auto lg:grid lg:w-full lg:max-w-7xl lg:grid-cols-2 lg:gap-x-8 lg:px-8">
<div class="lg:pr-4">
<div class="max-w-xl text-base leading-7 text-gray-700 lg:max-w-lg">
<p>Natster is an example of the kind of application you can build quickly and easily using nothing but NATS
<p>Natster is an example of the kind of application you can build quickly and easily using nothing but NATS.
</p>
<ul role="list" class="mt-8 space-y-8 text-gray-600">
<li class="flex gap-x-3">
Expand All @@ -49,12 +54,12 @@
<li class="flex gap-x-3">
<LockClosedIcon class="mt-1 h-5 w-5 flex-none text-indigo-600" aria-hidden="true" />
<span><strong class="font-semibold text-gray-900">Always encrypted.</strong>
Nothing you share can ever be read by anyone but the intended recipient. Synadia can't even read it.
Nothing you share can ever be read by anyone but the intended recipient.
</span>
</li>
<li class="flex gap-x-3">
<CogIcon class="mt-1 h-5 w-5 flex-none text-indigo-600" aria-hidden="true" />
<span><strong class="font-semibold text-gray-900">Nothing But NATs.</strong>
<span><strong class="font-semibold text-gray-900">Nothing But NATS.</strong>
NATS is more than a tool, it's a platform that gives us an easy button for building distributed apps.
</span>
</li>
Expand All @@ -67,7 +72,8 @@
</ul>
<p class="mt-8"></p>
<h2 class="mt-16 text-2xl font-bold tracking-tight text-gray-900">Need help? Slack us!</h2>
<p class="mt-6">The maintainers of Natster can be found hanging out in the NATs.io slack</p>
<p class="mt-6">The maintainers of Natster can be found hanging out in the <a href="https://slack.nats.io"
class="text-blue-500 underline">NATS.io slack</a>.</p>
</div>
</div>
</div>
Expand All @@ -85,14 +91,27 @@ import { notificationStore } from '../stores/notification'
import VCodeBlock from '@wdns/vue-code-block';
const natsterImg = new URL('@/assets/natster-horizontal.svg', import.meta.url)
const code = ref(`# Install the Natster CLI
const code_init = ref(`# Install the Natster CLI
curl -sSf https://natster.io/install.sh | sh
# Initialize the Natster with your Synadia Cloud Token
natster init --token <SYNADIA CLOUD TOKEN>
# Bind your OAuth ID with your Natster Account
natster auth web
natster login
# Verify your context was successfully bound
natster whoami
`);
const code_share = ref(`# Create a new catalog
natster catalog new
# Serve your catalog
natster catalog serve
# Share with your friends
natster catalog share
`);
const route = useRoute()
Expand Down
27 changes: 4 additions & 23 deletions natster-io/src/views/HomeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
A peer-to-multipeer media sharing application built with nothing but NATS and powered by
Synadia Cloud.
</p>
<div v-if="!codeProvided" class="mt-10 flex items-center gap-x-6">
<div class="mt-10 flex items-center gap-x-6">
<button @click.prevent="login"
class="rounded-md bg-indigo-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-400">
Login
Expand All @@ -66,7 +66,7 @@
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { userStore } from '../stores/user.js'
import { useAuth0 } from '@auth0/auth0-vue'
Expand All @@ -76,29 +76,10 @@ const natsterImg = new URL('@/assets/natster.svg', import.meta.url)
const natsterScreen = new URL('@/assets/natster_screen.png', import.meta.url)
const { loginWithRedirect } = useAuth0()
const codeProvided = computed(() => {
onMounted(() => {
const uStore = userStore()
if (
uStore.getOauthId != null &&
typeof uStore.getOauthId !== undefined &&
uStore.getOauthId !== ''
) {
console.log('Logging in with oauthid', uStore.getOauthId)
loginWithRedirect({
appState: {
target: '/library',
in_oauthid: uStore.getOauthId
},
authorizationParams: {
in_oauthid: uStore.getOauthId
}
})
return true
}
const route = useRoute()
if (route.params.code === undefined || route.params.code === '') {
return false
}
Expand Down
14 changes: 9 additions & 5 deletions natster/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func InitNatster(ctx *fisk.ParseContext) error {
}
if len(users.Items) == 0 {
// TODO: we should offer to create one here
return errors.New("a user context is required for natster to operate properly. No users found")
return errors.New("🛑 a user context is required for natster to operate properly. No users found")
}

usernames := make([]string, len(users.Items))
Expand Down Expand Up @@ -188,7 +188,11 @@ func InitNatster(ctx *fisk.ParseContext) error {
return err
}
globalClient := globalservice.NewClient(conn)
whoami, _ := globalClient.Whoami()
whoami, err := globalClient.Whoami()
if err != nil {
fmt.Printf("🛑 There was an error querying the global service for your context: %s\n", err.Error())
return nil
}
// if this is the first time initializing, the account projection should be empty,
// so we should emit the initialized event (which will then create the account projection)
if whoami == nil {
Expand All @@ -199,16 +203,16 @@ func InitNatster(ctx *fisk.ParseContext) error {
})
err = globalClient.PublishEvent(models.NatsterInitializedEventType, "none", "none", data)
if err != nil {
fmt.Printf("Failed to contact Natster global service to write account initialization event: %s", err)
fmt.Printf("🛑 Failed to contact Natster global service to write account initialization event: %s", err)
return err
}
} else {
t := time.Unix(whoami.Initialized, 0)
fmt.Printf("Note: this account was previously initialized on %s\n", t.Format("2006-01-02 15:04:05"))
}

fmt.Printf("Congratulations! Your account (%s) is ready to serve Natster catalogs!\n", accountName)
fmt.Println("To get started, you'll want to do the following:\n1. `natster catalog new` to create a catalog\n2. `natster catalog serve` to host the media catalog\n3. `natster catalog share` to share with friends.")
fmt.Printf("Your account (%s) has all prerequisites required to serve Natster catalogs.\n", accountName)
fmt.Println("Check the docs and more at https://docs.natster.io for more details.")

return nil
}
Expand Down
8 changes: 6 additions & 2 deletions natster/natster.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ func main() {
UnNegatableBoolVar(&HubOpts.AllowAll)
hub_up.Action(StartCatalogServer)

auth := ncli.Command("auth", "Authenticate your local context for use with natster.io")
auth := ncli.Command("auth", "Authenticate your local context for use with natster.io").Hidden()
weblogin := auth.Command("web", "Authenticate with one time code")
weblogin.Flag("qrcode", "Displays QR code in terminal of login link").Default("false").UnNegatableBoolVar(&WebLoginOpts.DisplayQR)
weblogin.Flag("qrcode", "Displays a QR code as well as the URL").Default("false").UnNegatableBoolVar(&WebLoginOpts.DisplayQR)
weblogin.Action(WebLogin)

login := ncli.Command("login", "Authenticate your local context for use with natster.io")
login.Flag("qrcode", "Displays a QR code as well as the URL").Default("false").UnNegatableBoolVar(&WebLoginOpts.DisplayQR)
login.Action(WebLogin)

claim := ncli.Command("claim", "Claims an OTC code. For testing only - Can only be done from the natster.io account").Hidden()
claim.Arg("code", "Previously generated one-time code").Required().StringVar(&ClaimOpts.Code)
claim.Arg("identity", "OAuth identity string").Required().StringVar(&ClaimOpts.OAuthIdentity)
Expand Down
1 change: 1 addition & 0 deletions natster/weblogin.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func WebLogin(ctx *fisk.ParseContext) error {
)

if WebLoginOpts.DisplayQR {
fmt.Printf("\n\nAlternatively, you can scan this QR code to claim your login code\n")
qrterminal.Generate(response.ClaimUrl, qrterminal.L, os.Stdout)
} else {
switch runtime.GOOS {
Expand Down

0 comments on commit a2c7c63

Please sign in to comment.