Skip to content

Commit

Permalink
Merge pull request #364 from big-armor/bugfix/DPM-357-Various-improve…
Browse files Browse the repository at this point in the history
…ments-5

bugfix/DPM-357 - Various Improvements 5
  • Loading branch information
traviscollins committed Jul 12, 2021
2 parents b57958c + d6bc1bb commit 7b8b19a
Show file tree
Hide file tree
Showing 14 changed files with 7,723 additions and 5,951 deletions.
13,518 changes: 7,653 additions & 5,865 deletions backend/package-lock.json

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
"@google-cloud/secret-manager": "^3.1.0",
"@google-cloud/storage": "^5.1.1",
"@types/fs-extra": "^9.0.11",
"@types/graphql-upload": "^8.0.6",
"@types/node-fetch": "^2.5.11",
"@types/nodemailer": "^6.4.0",
"@types/sharp": "^0.26.0",
"ajv": "^6.12.3",
"apollo-server": "^2.11.0",
"apollo-server": "^2.23.0",
"atob": "^2.1.2",
"await-lock": "^2.1.0",
"cron": "^1.8.2",
Expand Down Expand Up @@ -70,13 +72,13 @@
},
"devDependencies": {
"@apollo/client": "^3.0.0",
"@graphql-codegen/add": "^1.13.1",
"@graphql-codegen/cli": "^1.13.1",
"@graphql-codegen/introspection": "^1.17.8",
"@graphql-codegen/typed-document-node": "^1.17.9",
"@graphql-codegen/typescript": "^1.17.8",
"@graphql-codegen/typescript-operations": "1.17.8",
"@graphql-codegen/typescript-resolvers": "^1.17.8",
"@graphql-codegen/add": "^1.17.7",
"@graphql-codegen/cli": "^1.21.6",
"@graphql-codegen/introspection": "^1.18.2",
"@graphql-codegen/typed-document-node": "^1.18.9",
"@graphql-codegen/typescript": "^1.22.4",
"@graphql-codegen/typescript-operations": "^1.18.3",
"@graphql-codegen/typescript-resolvers": "^1.19.5",
"@types/atob": "^2.1.2",
"@types/chai": "^4.2.14",
"@types/cron": "^1.7.2",
Expand Down
4 changes: 2 additions & 2 deletions backend/src/directive/ValidPasswordDirective.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class ValidPasswordDirective extends SchemaDirectiveVisitor {
): GraphQLArgument | void | null {
const { resolve = defaultFieldResolver } = details.field;
details.field.resolve = function (source, args, context: Context, info) {
const password: string | undefined = args.password || args.value.password || undefined;
const password: string | undefined = args.password || args.value?.password || undefined;
validatePassword(password);
return resolve.apply(this, [source, args, context, info]);
};
Expand All @@ -36,7 +36,7 @@ export class ValidPasswordDirective extends SchemaDirectiveVisitor {
field.resolve = function (source, args, context: Context, info) {
const password: string | undefined = args.password || args.value.password || undefined;

validatePassword(args.password);
validatePassword(password);

return resolve.apply(this, [source, args, context, info]);
};
Expand Down
2 changes: 1 addition & 1 deletion backend/src/directive/ValidUsernameDirective.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SchemaDirectiveVisitor, ApolloError, ValidationError } from "apollo-server";
import { SchemaDirectiveVisitor, ValidationError } from "apollo-server";
import { Kind } from "graphql";
import {
GraphQLField,
Expand Down
16 changes: 0 additions & 16 deletions backend/src/util/jwt.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { promisify } from "util";
import { AuthenticationError, ApolloError } from "apollo-server";
import { EntityManager } from "typeorm";
import jwks from "jwks-rsa";
import jwt from "jsonwebtoken";
import express from "express";
import fetch from "node-fetch";

import { UserEntity } from "../entity/UserEntity";
import { getEnvVariable } from "./getEnvVariable";
Expand Down Expand Up @@ -98,15 +94,3 @@ export function createJwt(user: UserEntity): string {
issuer: getEnvVariable("JWT_ISSUER")
});
}

interface UserInfo {
sub: string;
given_name?: string;
family_name?: string;
nickname?: string;
name: string;
picture: string;
updated_at: string;
emailAddress: string;
email_verified: boolean;
}
4 changes: 2 additions & 2 deletions backend/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es2017",
"target": "es2019",
"outDir": "dist",
"moduleResolution": "node",
"module": "commonjs",
Expand Down Expand Up @@ -35,7 +35,7 @@
"emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
"resolveJsonModule": true,

"lib": ["es2017", "dom"],
"lib": ["es2019", "dom"],
"typeRoots": ["node_modules/@types", "src/types"]
},

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/markdown-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function buildMarkedOptionsFactory(): MarkedOptions {
const renderer = new MarkedRenderer();

renderer.blockquote = (text: string) => {
return '<blockquote class="markdown-quote-block"><p>' + text + "</p></blockquote>";
return "<blockquote><p>" + text + "</p></blockquote>";
};

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { Component, Input } from "@angular/core";
import { Component } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { PackageFile, parsePackageFileJSON, Schema, validatePackageFileInBrowser } from "datapm-lib";
import { Subject } from "rxjs";
import { takeUntil } from "rxjs/operators";
import {
User,
Collection,
Package,
PackageCollectionsGQL,
PackageIdentifierInput,
MovePackageGQL,
Permission
} from "src/generated/graphql";
import { Collection, Package, PackageCollectionsGQL, PackageIdentifierInput, Permission } from "src/generated/graphql";
import { PackageService, PackageResponse } from "../../services/package.service";
@Component({
selector: "package-description",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@
<div class="accordions-group mt-2">
<mat-accordion class="schema-property" multi>
<mat-expansion-panel
*ngFor="
let property of schema?.properties
| values
| sortBy: 'asc':'title'
| slice: 0:propertiesToShowCount
"
*ngFor="let property of schema?.properties | values | sortBy: 'asc':'title'; let i = index"
[id]="getPropertyId(property)"
[expanded]="getPropertyId(property) == focusedPropertyId"
[hidden]="propertiesToShowCount < i + 1"
>
<mat-expansion-panel-header>
<mat-panel-title class="text-dark-gray weight-500">
Expand All @@ -40,8 +36,12 @@
</mat-expansion-panel-header>
<div>
<div class="text-dark-gray mb-2">
<a class="cursor-pointer doc-link" (click)="editPropertyDialog(property)">Edit Property</a>
<span class="px-2">|</span>
<ng-container *ngIf="hasEditPermissions">
<a class="cursor-pointer doc-link" (click)="editPropertyDialog(property)"
>Edit Property</a
>
<span class="px-2">|</span>
</ng-container>
<a class="cursor-pointer doc-link" (click)="createIssue(property)">Create Issue</a>
<span class="px-2">|</span>
<a class="cursor-pointer doc-link" (click)="copyLink(property)">Copy Link</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
import {
AfterViewChecked,
AfterViewInit,
ChangeDetectorRef,
Component,
ElementRef,
Input,
OnChanges,
OnDestroy,
QueryList,
OnInit,
ViewChildren
} from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { Title } from "@angular/platform-browser";
import { ActivatedRoute, Router } from "@angular/router";
import { PackageFile, Schema, ValueTypeStatistics } from "datapm-lib";
import { Subject } from "rxjs";
import { Clipboard } from "@angular/cdk/clipboard";
import { SnackBarService } from "src/app/services/snackBar.service";
import { SamplesFullScreenDialog } from "../package-samples/samples-fullscreen-dialog.component";
import { EditPropertyDialogComponent } from "./edit-property-dialog/edit-property-dialog.component";
import { getRegistryURL } from "src/app/helpers/RegistryAccessHelper";
import { packageToIdentifier } from "src/app/helpers/IdentifierHelper";
import { Package } from "src/generated/graphql";
import { Package, Permission } from "src/generated/graphql";
import { MatExpansionPanel } from "@angular/material/expansion";

@Component({
selector: "schema",
templateUrl: "./package-schema.component.html",
styleUrls: ["./package-schema.component.scss"]
})
export class PackageSchemaComponent implements OnDestroy, OnChanges, AfterViewInit {
export class PackageSchemaComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
private readonly MAX_PROPERTIES_TO_SHOW_INITIALLY = 10;

@Input()
Expand All @@ -51,6 +47,8 @@ export class PackageSchemaComponent implements OnDestroy, OnChanges, AfterViewIn

public focusedPropertyId: string;

public hasEditPermissions: boolean;

private unsubscribe$ = new Subject();

constructor(
Expand All @@ -67,30 +65,40 @@ export class PackageSchemaComponent implements OnDestroy, OnChanges, AfterViewIn
this.schemaPropertiesLength(this.schema) > this.MAX_PROPERTIES_TO_SHOW_INITIALLY;
}

public ngOnInit(): void {
this.hasEditPermissions = this.package.myPermissions.includes(Permission.EDIT);
}

public ngAfterViewInit(): void {
const fragment = this.route.snapshot.fragment;
if (fragment) {
const el: any = document.getElementById(fragment);
if (el) {
this.focusedPropertyId = fragment;
el.scrollIntoView({ behavior: "smooth" });
this.cdr.detectChanges();
if (el.hidden) {
this.toggleShowMoreProperties();
}

setTimeout(() => {
this.focusedPropertyId = fragment;
el.scrollIntoView({ behavior: "smooth" });
this.cdr.detectChanges();
});
}
}
}

public ngOnDestroy(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}

public toggleShowMoreProperties(): void {
this.isShowingMorePropertiesText = !this.isShowingMorePropertiesText;
this.propertiesToShowCount = this.isShowingMorePropertiesText
? this.schemaPropertiesLength(this.schema)
: this.MAX_PROPERTIES_TO_SHOW_INITIALLY;
}

public ngOnDestroy(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}

public getPropertyTypes(property: Schema): string {
const keys = Object.keys(property.valueTypes).sort();
return keys.join(",");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h1 class="dialog-title pb-2">datapm</h1>
autocomplete="rutjfkde"
inputType="password"
class="rounded-input"
[error]="signUpForm | inputError: 'password' | async"
[error]="signUpForm | inputError: 'password':errorMessages['password'] | async"
></app-input>

<br />
Expand Down Expand Up @@ -57,7 +57,7 @@ <h1 class="dialog-title pb-2">datapm</h1>
</div>

<div class="text-center">
<button type="submit" class="app-raised-button" [disabled]="!signUpForm.valid">
<button type="submit" class="app-raised-button">
<span class="btn-text">Sign Up</span>
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FormControl, FormGroup, Validators } from "@angular/forms";
import { CreateMeGQL, EmailAddressAvailableGQL, UsernameAvailableGQL } from "src/generated/graphql";
import { MatSnackBar } from "@angular/material/snack-bar";
import { MatDialogRef } from "@angular/material/dialog";
import { usernameValidator, emailAddressValidator } from "src/app/helpers/validators";
import { usernameValidator, emailAddressValidator, newPasswordValidator } from "src/app/helpers/validators";
import { UiStyleToggleService } from "src/app/services/ui-style-toggle.service";
import { Subject } from "rxjs";
import { takeUntil } from "rxjs/operators";
Expand All @@ -26,11 +26,10 @@ enum State {
export class SignUpDialogComponent implements OnInit {
private readonly destroy = new Subject<void>();

State = State;
public State = State;
public state = State.INIT;

state = State.INIT;

signUpForm: FormGroup;
public signUpForm: FormGroup;

public errorMessages = {
emailAddress: {
Expand All @@ -45,6 +44,12 @@ export class SignUpDialogComponent implements OnInit {
TOO_LONG: "Username must be less than 40 characters long.",
NOT_AVAILABLE: "That username is not available. Try a different username.",
RESERVED_KEYWORD: "The username you used is a restricted keyword. Please choose another name"
},
password: {
INVALID_CHARACTERS: "Password must contain letters and at least a number.",
PASSWORD_TOO_LONG: "Password must be less than 99 characters long.",
PASSWORD_TOO_SHORT: "Password must be more than 8 characters long.",
REQUIRED: "Password is required."
}
};

Expand All @@ -61,7 +66,7 @@ export class SignUpDialogComponent implements OnInit {
private uiStyleToggleService: UiStyleToggleService
) {}

ngOnInit(): void {
public ngOnInit(): void {
this.uiStyleToggleService.DARK_MODE_ENABLED.pipe(takeUntil(this.destroy)).subscribe(
(darkModeEnabled) => (this.darkModeEnabled = darkModeEnabled)
);
Expand All @@ -78,12 +83,13 @@ export class SignUpDialogComponent implements OnInit {
updateOn: "blur"
}),
password: new FormControl("", {
validators: [Validators.required]
asyncValidators: [newPasswordValidator()],
updateOn: "blur"
})
});
}

formSubmit() {
public formSubmit(): void {
this.signUpForm.markAllAsTouched();
if (this.signUpForm.invalid) {
return;
Expand Down Expand Up @@ -116,6 +122,7 @@ export class SignUpDialogComponent implements OnInit {
});
}

this.state = State.ERROR;
return;
}

Expand All @@ -128,21 +135,10 @@ export class SignUpDialogComponent implements OnInit {
verticalPosition: "top",
horizontalPosition: "right"
});
this.state = State.ERROR;
});
}

openForgotPassword() {
this.dialogRef.close("forgotPassword");
}

clearError(field: string) {
const control = this.signUpForm.get(field);
if (control.errors !== null) {
control.setErrors(null);
this.componentChangeDetector.detectChanges();
}
}

openLoginDialog(ev: any) {
ev.preventDefault();
this.dialogRef.close();
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/shared/pipes/input-error.pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const defaultMessages = {
INVALID_CHARACTERS: (errors: any) =>
"Passwords less than 16 characters must include one number or a special character (@ # $ % !)",
INVALID_FORMAT: (errors: any) => "Invalid format",
INVALID_EMAIL_ADDRESS_FORMAT: (errors: any) => "Not a valid email address",
TOO_LONG: (errors: any) => "Too long",
RESERVED_KEYWORD: (errors: any) => "This is a reserved keyword. Please choose a different word",
PASSWORDS_DONT_MATCH: (errors: any) => "The entered passwords must match."
Expand All @@ -32,6 +33,7 @@ const errorKeys = [
"USERNAME_TOO_LONG",
"NOT_AVAILABLE",
"INVALID_FORMAT",
"INVALID_EMAIL_ADDRESS_FORMAT",
"TOO_LONG",
"RESERVED_KEYWORD",
"PASSWORDS_DONT_MATCH"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,7 @@ button:disabled {
transition: color 0.5s, background 0.5s;
}

.markdown-quote-block {
blockquote {
color: var(--gray-3-color);
border-left: 2px solid var(--gray-5-color);
padding-left: 10px;
Expand Down

0 comments on commit 7b8b19a

Please sign in to comment.