Skip to content

Commit

Permalink
Fixes platform connection (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardocustodio authored Jul 31, 2023
1 parent a246fb1 commit af0cbfb
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 109 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/public/storage
/storage/*.key
/vendor
/resources/js/config.json
.env
.env.backup
.env.production
Expand Down
8 changes: 4 additions & 4 deletions resources/js/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class ApiService {

if (resp.status === 401) {
useAppStore().clearLogin();
snackbar.error({ title: 'Unauthorized', text: 'Session exipred, try to sign in again' });
snackbar.error({ title: 'Unauthorized', text: 'Session expired, try to sign in again' });
throw [{ field: 'Error', message: 'Unauthorized' }];
}

Expand All @@ -60,7 +60,7 @@ export class ApiService {

return new Promise((resolve, reject) => {
ApiService.request({
url: `${appStore.config.protocol}//${appStore.config.hostname}/graphql${schema}`,
url: `${appStore.config.url}graphql${schema}`,
data,
credentials: useAppStore().isMultiTenant ? 'include' : 'omit',
}).then((res: any) => {
Expand All @@ -85,9 +85,9 @@ export class ApiService {
});
}

static async fetchHostname(hostname: string, protocol: string) {
static async fetchURL(url: URL) {
return ApiService.request({
url: `${protocol}//${hostname}/.well-known/enjin-platform.json`,
url: `${url}.well-known/enjin-platform.json`,
method: HttpMethods.GET,
credentials: undefined,
mode: import.meta.env.PROD ? 'cors' : undefined,
Expand Down
43 changes: 14 additions & 29 deletions resources/js/components/pages/Setup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
<div class="bg-white px-4 py-8 shadow sm:rounded-lg sm:px-10">
<Form ref="formRef" class="space-y-6" :validation-schema="validation" @submit="setupAccount">
<FormInput
v-model="hostname"
label="Hostname"
name="hostname"
v-model="url.origin"
label="Enjin Platform URL"
name="url"
input-class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary sm:text-sm sm:leading-6"
/>
<FormInput
v-if="!appStore.isMultiTenant"
v-model="authorizationToken"
label="Authroization token"
label="Authorization Token"
name="authorization"
input-class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary sm:text-sm sm:leading-6"
type="password"
Expand All @@ -32,6 +32,7 @@
<script setup lang="ts">
import { Form } from 'vee-validate';
import { ref } from 'vue';
import type { Ref } from 'vue';
import { useRouter } from 'vue-router';
import { useAppStore } from '~/store';
import Btn from '~/components/Btn.vue';
Expand All @@ -44,15 +45,15 @@ const router = useRouter();
const appStore = useAppStore();
const isLoading = ref(false);
const hostname = ref('');
const url: Ref<URL | undefined> = ref();
const authorizationToken = ref('');
const formRef = ref();
const validation = yup.object().shape({
hostname: yup.string().required('Hostname is required'),
url: yup.string().required('The URL is required'),
authorization: yup.string().when('tenant', {
is: false,
then: () => yup.string().required('Authorization token is required'),
then: () => yup.string().required('The authorization token is required'),
}),
});
Expand All @@ -65,36 +66,20 @@ const isValid = async () => {
return formRef.value.getMeta().valid;
};
const parseHostname = (hostname: string) => {
try {
const url = new URL(hostname);
return url;
} catch {
return { hostname: hostname, protocol: 'https:', port: '' };
}
};
const setupAccount = async () => {
try {
if (!(await isValid())) return;
isLoading.value = true;
const hostnameParse = parseHostname(hostname.value);
if (!hostnameParse) {
throw new Error('Invalid hostname');
}
if (window.location.protocol === 'https:' && hostnameParse?.protocol === 'http:') {
if (window.location.protocol === 'https:' && url.value?.protocol === 'http:') {
throw new Error('You must use an https hostname');
}
const fullHostname = hostnameParse.hostname + (hostnameParse.port ? `:${hostnameParse.port}` : '');
if (!(await appStore.checkHostname(fullHostname, hostnameParse.protocol))) return;
const parsedUrl = new URL(url.value!);
if (!(await appStore.checkURL(parsedUrl))) return;
await appStore.setupAccount({
hostname: fullHostname,
protocol: hostnameParse.protocol,
url: parsedUrl,
authorization_token: authorizationToken.value,
});
redirectToCollections();
Expand All @@ -106,7 +91,7 @@ const setupAccount = async () => {
};
(async () => {
if (appStore.config.hostname && appStore.config.authorization_token) redirectToCollections();
hostname.value = appStore.config.hostname as string;
if (appStore.config.url && appStore.config.authorization_token) redirectToCollections();
url.value = appStore.config.url as URL;
})();
</script>
8 changes: 0 additions & 8 deletions resources/js/config.json

This file was deleted.

2 changes: 1 addition & 1 deletion resources/js/config.json.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"hostname": "HOSTNAME_VALUE",
"url": "URL_VALUE",
"authorization_token": "AUTHORIZATION_TOKEN_VALUE",
"route": "ROUTE_VALUE",
"tenant": MULTI_TENANCY_VALUE,
Expand Down
90 changes: 28 additions & 62 deletions resources/js/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,28 @@ import snackbar from '~/util/snackbar';
import { AuthApi } from '~/api/auth';
import { CollectionApi } from '~/api/collection';

const parseConfigHostname = (hostname: string): string => {
const parseConfigURL = (url: string): URL => {
try {
const url = new URL(hostname);

if (url.port.length) {
return `${url.hostname}:${url.port}`;
}

return url.hostname;
return new URL(url);
} catch {
return hostname;
}
};

const parseConfigProtocol = (hostname: string) => {
try {
const url = new URL(hostname);

if (url.protocol.length) return url.protocol;

return null;
} catch {
return 'https:';
return new URL('https://' + url);
}
};

export const useAppStore = defineStore('app', {
state: (): AppState => ({
hostname: '',
url: undefined,
authorization_token: '',
protocol: 'https',
advanced: false,
config: {
hostname: '',
url: undefined,
authorization_token: '',
route: '',
network: '',
packages: [],
tenant: false,
webSocket: '',
channel: '',
protocol: '',
},
navigations: [
{ name: 'Collections', to: { name: 'platform.collections' }, pos: 1 },
Expand All @@ -61,20 +41,20 @@ export const useAppStore = defineStore('app', {
user: null,
}),
persist: {
paths: ['hostname', 'authorization_token', 'loggedIn', 'advanced', 'protocol'],
paths: ['url', 'authorization_token', 'loggedIn', 'advanced'],
},
actions: {
async init() {
try {
this.setConfig();
if (!this.config.hostname) return;
if (!this.config.url) return;

if (this.isMultiTenant && this.loggedIn) await this.getUser();
const hostnameConfig = await this.checkHostname(this.config.hostname, this.config.protocol);
this.config.network = hostnameConfig.network;
this.config.packages = Object.entries(hostnameConfig.packages).map(([key, value]: any[]) => {
const urlConfig = await this.checkURL(this.config.url);
this.config.network = urlConfig.network;
this.config.packages = Object.entries(urlConfig.packages).map(([key, value]: any[]) => {
let link =
hostnameConfig.url +
urlConfig.url +
'/graphiql/' +
(key === 'enjin/platform-core' ? '' : key.replace('enjin/platform-', ''));
if (key === 'enjin/platform-ui') link = '';
Expand All @@ -89,7 +69,8 @@ export const useAppStore = defineStore('app', {
if (this.hasBeamPackage) this.addBeamNavigation();
if (this.hasFuelTanksPackage) this.addFuelTanksNavigation();
if (this.hasMarketplacePackage) this.addMarketplaceNavigation();
this.fetchCollectionIds();

await this.fetchCollectionIds();

return true;
} catch (error: any) {
Expand All @@ -99,32 +80,17 @@ export const useAppStore = defineStore('app', {

return false;
},
async setupAccount({
hostname,
authorization_token,
protocol,
}: {
hostname: string;
authorization_token: string;
protocol: string;
}) {
this.hostname = hostname;
this.protocol = protocol;
this.config.protocol = protocol;
this.config.hostname = hostname;
async setupAccount({ url, authorization_token }: { url: URL; authorization_token: string }) {
this.url = url;
this.authorization_token = authorization_token;
this.config.authorization_token = authorization_token;
this.loggedIn = true;
await this.init();
},
setConfig() {
if (appConfig?.hostname?.length) this.config.hostname = parseConfigHostname(appConfig.hostname);
else if (window?.bootstrap?.hostname) this.config.hostname = parseConfigHostname(window.bootstrap.hostname);
else this.config.hostname = this.hostname;

if (appConfig?.hostname?.length && parseConfigProtocol(appConfig.hostname))
this.config.protocol = parseConfigProtocol(appConfig.hostname) ?? '';
else this.config.protocol = this.protocol;
if (appConfig?.url) this.config.url = parseConfigURL(appConfig.url);
else if (window?.bootstrap?.hostname) this.config.url = parseConfigURL(window.location.origin);
else this.config.url = this.url;

if (appConfig?.authorization_token?.length) this.config.authorization_token = appConfig.authorization_token;
else this.config.authorization_token = this.authorization_token;
Expand All @@ -134,18 +100,18 @@ export const useAppStore = defineStore('app', {
if (appConfig.websocket.length) this.config.webSocket = appConfig.websocket;
if (appConfig.channel.length) this.config.channel = appConfig.channel;
},
async checkHostname(hostname: string, protocol: string) {
async checkURL(url: URL) {
try {
if (hostname) {
const hostnameConfig = await ApiService.fetchHostname(hostname, protocol);
if (hostnameConfig) return hostnameConfig;
if (url) {
const urlConfig = await ApiService.fetchURL(url);
if (urlConfig) return urlConfig;

throw 'Hostname is not valid';
throw 'The URL is not valid';
}

return null;
} catch {
throw 'Hostname is not valid';
throw 'The URL is not valid';
}
},
async getUser() {
Expand Down Expand Up @@ -200,9 +166,9 @@ export const useAppStore = defineStore('app', {
await AuthApi.revokeApiTokens([name]);
this.user.apiTokens = this.user.apiTokens.filter((token) => token.name !== name);
},
setHostname(hostname: string) {
this.hostname = hostname;
this.config.hostname = hostname;
setURL(url: string) {
this.url = new URL(url);
this.config.url = new URL(url);
},
setAuthorizationToken(authorization_token: string) {
this.authorization_token = authorization_token;
Expand Down Expand Up @@ -245,7 +211,7 @@ export const useAppStore = defineStore('app', {
return state.loggedIn && state.user?.apiTokens?.length > 0 && state.user?.account;
}

return state.loggedIn && state.config.hostname.length > 0 && state.config.authorization_token.length > 0;
return state.loggedIn && state.config.url && state.config.authorization_token.length > 0;
},
isMultiTenant(state: AppState) {
return state.config.tenant;
Expand Down
6 changes: 2 additions & 4 deletions resources/js/types/types.interface.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { BeamType, NotificationType, TokenCapType, TokenIdSelectType } from './types.enums';

export interface AppState {
hostname: string;
url?: URL;
authorization_token: string;
advanced: boolean;
protocol: string;
config: {
hostname: string;
url?: URL;
authorization_token: string;
route: string;
network: string;
packages: { name: string; version: string; link?: string }[];
tenant: boolean;
webSocket: string;
channel: string;
protocol: string;
};
navigations: any[];
collections: string[];
Expand Down
2 changes: 1 addition & 1 deletion src/Console/InstallPlatformUi.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function handle()

$tenant = $this->askForInput('Do you want to enable Multi tenancy? (yes/no)', 'MULTI_TENANCY_VALUE', 'false', 'tenant');

$this->askForInput('Please enter your platform Hostname', 'HOSTNAME_VALUE', '', 'host');
$this->askForInput('Please enter your platform Hostname', 'URL_VALUE', '', 'host');

if ($tenant !=='true') {
$this->askForInput('Please enter an Authorization token', 'AUTHORIZATION_TOKEN_VALUE', '', 'token');
Expand Down

0 comments on commit af0cbfb

Please sign in to comment.