Add app info dialog
This commit is contained in:
parent
3c1f07f3b0
commit
3992429236
15 changed files with 254 additions and 3 deletions
23
backend/package-lock.json
generated
23
backend/package-lock.json
generated
|
@ -1412,6 +1412,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
|
||||||
},
|
},
|
||||||
|
"cross-fetch": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "2.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
|
@ -2056,6 +2064,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
||||||
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
|
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
|
||||||
},
|
},
|
||||||
|
"extract-files": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="
|
||||||
|
},
|
||||||
"fast-decode-uri-component": {
|
"fast-decode-uri-component": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
|
||||||
|
@ -2484,6 +2497,16 @@
|
||||||
"lodash.get": "^4.4.2"
|
"lodash.get": "^4.4.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"graphql-request": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==",
|
||||||
|
"requires": {
|
||||||
|
"cross-fetch": "^3.0.6",
|
||||||
|
"extract-files": "^9.0.0",
|
||||||
|
"form-data": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"graphql-subscriptions": {
|
"graphql-subscriptions": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.1.0.tgz",
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
"fastify-sensible": "^3.1.0",
|
"fastify-sensible": "^3.1.0",
|
||||||
"fastify-session": "^5.2.1",
|
"fastify-session": "^5.2.1",
|
||||||
"got": "^11.8.1",
|
"got": "^11.8.1",
|
||||||
|
"graphql-request": "^3.4.0",
|
||||||
|
"graphql-tag": "^2.11.0",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"mongodb": "^3.6.3",
|
"mongodb": "^3.6.3",
|
||||||
"nanoid": "^3.1.20",
|
"nanoid": "^3.1.20",
|
||||||
|
|
|
@ -28,6 +28,12 @@ export default class Application extends BaseEntity {
|
||||||
@Column()
|
@Column()
|
||||||
public redirectUris!: string[];
|
public redirectUris!: string[];
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
public ownerGitHubLogin!: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
public homepage!: string | null;
|
||||||
|
|
||||||
public static generateClientId(): string {
|
public static generateClientId(): string {
|
||||||
return nanoid(12);
|
return nanoid(12);
|
||||||
}
|
}
|
||||||
|
|
20
backend/src/graphql/github/queries/get-user.ts
Normal file
20
backend/src/graphql/github/queries/get-user.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import gql from 'graphql-tag';
|
||||||
|
|
||||||
|
export const getUserQuery = gql`query GetUser($login: String!) {
|
||||||
|
user(login: $login) {
|
||||||
|
login
|
||||||
|
name
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
login: string;
|
||||||
|
name: string | null;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetUserQueryResult {
|
||||||
|
user: User
|
||||||
|
}
|
14
backend/src/graphql/github/sdk.ts
Normal file
14
backend/src/graphql/github/sdk.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { GraphQLClient } from 'graphql-request';
|
||||||
|
import { requireEnv } from '../../utils';
|
||||||
|
import type { GetUserQueryResult, User } from './queries/get-user';
|
||||||
|
import { getUserQuery } from './queries/get-user';
|
||||||
|
|
||||||
|
const client = new GraphQLClient('https://api.github.com/graphql');
|
||||||
|
client.setHeader('Authorization', `bearer ${requireEnv('GITHUB_API_TOKEN')}`);
|
||||||
|
|
||||||
|
export async function getUser(login: string): Promise<User> {
|
||||||
|
const { user } = await client.request<GetUserQueryResult>(getUserQuery, {
|
||||||
|
login,
|
||||||
|
});
|
||||||
|
return user;
|
||||||
|
}
|
15
backend/src/routes/website-api/models/github-user.ts
Normal file
15
backend/src/routes/website-api/models/github-user.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Field, ObjectType } from 'type-graphql';
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
export default class GitHubUser {
|
||||||
|
@Field(() => String)
|
||||||
|
public login!: string;
|
||||||
|
|
||||||
|
@Field(() => String, {
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public name!: string | null;
|
||||||
|
|
||||||
|
@Field(() => String)
|
||||||
|
public url!: string;
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { Field, ObjectType } from 'type-graphql';
|
import { Field, ObjectType } from 'type-graphql';
|
||||||
|
import GitHubUser from './github-user';
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
export default class PromptInfoApplication {
|
export default class PromptInfoApplication {
|
||||||
|
@ -15,4 +16,12 @@ export default class PromptInfoApplication {
|
||||||
|
|
||||||
@Field(() => Boolean)
|
@Field(() => Boolean)
|
||||||
public verified!: boolean;
|
public verified!: boolean;
|
||||||
|
|
||||||
|
@Field(() => GitHubUser)
|
||||||
|
public owner!: GitHubUser;
|
||||||
|
|
||||||
|
@Field(() => String, {
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public homepage!: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
Arg, Ctx, FieldResolver, Query, Resolver, Root,
|
Arg, Ctx, FieldResolver, Query, Resolver, Root,
|
||||||
} from 'type-graphql';
|
} from 'type-graphql';
|
||||||
import database from '../../../database/database';
|
import database from '../../../database/database';
|
||||||
|
import { getUser } from '../../../graphql/github/sdk';
|
||||||
import { UnknownPromptError } from '../errors';
|
import { UnknownPromptError } from '../errors';
|
||||||
import PromptInfo from '../models/prompt-info';
|
import PromptInfo from '../models/prompt-info';
|
||||||
import type PromptInfoApplication from '../models/prompt-info-application';
|
import type PromptInfoApplication from '../models/prompt-info-application';
|
||||||
|
@ -39,6 +40,8 @@ export default class PromptInfoResolver implements ResolverInterface<PromptInfo>
|
||||||
iconUrl: application.iconUrl,
|
iconUrl: application.iconUrl,
|
||||||
iconColor: application.iconColor,
|
iconColor: application.iconColor,
|
||||||
verified: application.verified,
|
verified: application.verified,
|
||||||
|
homepage: application.homepage,
|
||||||
|
owner: await getUser(application.ownerGitHubLogin),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
<template>
|
||||||
|
<v-dialog v-model="value" max-width="450">
|
||||||
|
<template #activator="{ on: dialogOn }">
|
||||||
|
<v-tooltip bottom>
|
||||||
|
<template #activator="{ on: tooltipOn }">
|
||||||
|
<v-card
|
||||||
|
class="d-inline-block px-1"
|
||||||
|
color="primary--text"
|
||||||
|
rounded
|
||||||
|
flat
|
||||||
|
v-on="{ ...dialogOn, ...tooltipOn }"
|
||||||
|
link
|
||||||
|
>
|
||||||
|
{{ promptInfo.application.name }}
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
Kliknij aby zobaczyć informacje o aplikacji
|
||||||
|
</v-tooltip>
|
||||||
|
</template>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
Informacje o aplikacji
|
||||||
|
</v-card-title>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-information</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-subtitle class="text-overline">
|
||||||
|
Nazwa aplikacji
|
||||||
|
</v-list-item-subtitle>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ promptInfo.application.name }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
v-if="promptInfo.application.homepage"
|
||||||
|
:href="promptInfo.application.homepage"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-home</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-subtitle class="text-overline">
|
||||||
|
Strona domowa
|
||||||
|
</v-list-item-subtitle>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ promptInfo.application.homepage }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
:href="promptInfo.application.owner.url"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-github</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-subtitle class="text-overline">
|
||||||
|
Twórca
|
||||||
|
</v-list-item-subtitle>
|
||||||
|
<v-list-item-title v-if="promptInfo.application.owner.name">
|
||||||
|
{{ promptInfo.application.owner.name }}
|
||||||
|
<span class="text--secondary">
|
||||||
|
({{ promptInfo.application.owner.login }})
|
||||||
|
</span>
|
||||||
|
</v-list-item-title>
|
||||||
|
<v-list-item-title v-else>
|
||||||
|
{{ promptInfo.application.owner.login }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
<v-alert
|
||||||
|
color="green"
|
||||||
|
icon="mdi-check"
|
||||||
|
text
|
||||||
|
class="mx-2"
|
||||||
|
v-if="promptInfo.application.verified"
|
||||||
|
>
|
||||||
|
Aplikacja zweryfikowana
|
||||||
|
</v-alert>
|
||||||
|
<v-alert
|
||||||
|
color="grey darken-2"
|
||||||
|
icon="mdi-close"
|
||||||
|
text
|
||||||
|
class="mx-2"
|
||||||
|
v-else
|
||||||
|
>
|
||||||
|
Aplikacja nie została zweryfikowana
|
||||||
|
</v-alert>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn color="primary" text @click="value = false">Zamknij</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
|
import { PromptInfo } from '@/types';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'AppInfoDialog',
|
||||||
|
})
|
||||||
|
export default class AppInfoDialog extends Vue {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: Object,
|
||||||
|
})
|
||||||
|
promptInfo!: PromptInfo;
|
||||||
|
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="pt-16">
|
<div class="pt-16">
|
||||||
<h2 class="text-subtitle-1 text--secondary mt-6 mb-2 px-4">
|
<h2 class="text-subtitle-1 text--secondary mt-6 mb-2 px-4">
|
||||||
Aplikacja
|
Aplikacja
|
||||||
<span class="text--primary">{{ promptInfo.application.name }}</span>
|
<app-info-dialog :prompt-info="promptInfo" />
|
||||||
chce uzyskać dostęp do twojego konta VULCAN UONET+ przez Wulkanowy Bridge
|
chce uzyskać dostęp do twojego konta VULCAN UONET+ przez Wulkanowy Bridge
|
||||||
</h2>
|
</h2>
|
||||||
<v-subheader>Uprawnienia aplikacji</v-subheader>
|
<v-subheader>Uprawnienia aplikacji</v-subheader>
|
||||||
|
@ -46,9 +46,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
import { PromptInfo } from '@/types';
|
import { PromptInfo } from '@/types';
|
||||||
|
import AppInfoDialog from '@/compontents/authenticate-prompt-windows/app-info-dialog.vue';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
name: 'OverviewWindow',
|
name: 'OverviewWindow',
|
||||||
|
components: { AppInfoDialog },
|
||||||
})
|
})
|
||||||
export default class OverviewWindow extends Vue {
|
export default class OverviewWindow extends Vue {
|
||||||
@Prop({
|
@Prop({
|
||||||
|
|
|
@ -31,5 +31,9 @@ export default class DialogApp extends Vue {
|
||||||
.v-card__text, .v-card__title {
|
.v-card__text, .v-card__title {
|
||||||
word-break: normal;
|
word-break: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-basis {
|
||||||
|
flex-basis: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -45,6 +45,15 @@ export type PromptInfoApplication = {
|
||||||
iconUrl: Maybe<Scalars['String']>;
|
iconUrl: Maybe<Scalars['String']>;
|
||||||
iconColor: Scalars['String'];
|
iconColor: Scalars['String'];
|
||||||
verified: Scalars['Boolean'];
|
verified: Scalars['Boolean'];
|
||||||
|
owner: GitHubUser;
|
||||||
|
homepage: Maybe<Scalars['String']>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GitHubUser = {
|
||||||
|
__typename?: 'GitHubUser';
|
||||||
|
login: Scalars['String'];
|
||||||
|
name: Maybe<Scalars['String']>;
|
||||||
|
url: Scalars['String'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Mutation = {
|
export type Mutation = {
|
||||||
|
@ -101,7 +110,11 @@ export type GetPromptInfoQuery = (
|
||||||
& Pick<PromptInfo, 'id' | 'scopes' | 'studentsMode'>
|
& Pick<PromptInfo, 'id' | 'scopes' | 'studentsMode'>
|
||||||
& { application: (
|
& { application: (
|
||||||
{ __typename?: 'PromptInfoApplication' }
|
{ __typename?: 'PromptInfoApplication' }
|
||||||
& Pick<PromptInfoApplication, 'name' | 'iconUrl' | 'iconColor' | 'verified'>
|
& Pick<PromptInfoApplication, 'name' | 'iconUrl' | 'iconColor' | 'verified' | 'homepage'>
|
||||||
|
& { owner: (
|
||||||
|
{ __typename?: 'GitHubUser' }
|
||||||
|
& Pick<GitHubUser, 'login' | 'name' | 'url'>
|
||||||
|
); }
|
||||||
); }
|
); }
|
||||||
); }
|
); }
|
||||||
);
|
);
|
||||||
|
@ -133,6 +146,12 @@ export const GetPromptInfoDocument = gql`
|
||||||
iconUrl
|
iconUrl
|
||||||
iconColor
|
iconColor
|
||||||
verified
|
verified
|
||||||
|
homepage
|
||||||
|
owner {
|
||||||
|
login
|
||||||
|
name
|
||||||
|
url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,12 @@ export default gql`query GetPromptInfo($promptId: String!) {
|
||||||
iconUrl
|
iconUrl
|
||||||
iconColor
|
iconColor
|
||||||
verified
|
verified
|
||||||
|
homepage
|
||||||
|
owner {
|
||||||
|
login
|
||||||
|
name
|
||||||
|
url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.authenticate-prompt-app {
|
.authenticate-prompt-app {
|
||||||
.avatar-sheet {
|
.avatar-sheet {
|
||||||
border-radius: 50%;
|
border-radius: 50% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fill-height {
|
.fill-height {
|
||||||
|
|
|
@ -13,6 +13,12 @@ export interface PromptInfo {
|
||||||
iconUrl: string | null;
|
iconUrl: string | null;
|
||||||
iconColor: string;
|
iconColor: string;
|
||||||
verified: boolean;
|
verified: boolean;
|
||||||
|
homepage: string | null;
|
||||||
|
owner: {
|
||||||
|
login: string;
|
||||||
|
name: string | null;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue