Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imolorhe/test deploy #2123

Merged
merged 9 commits into from Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .dockerignore
@@ -0,0 +1,7 @@
.git

**/node_modules
packages/altair-app
packages/altair-electron
packages/altaur-dashboard
site
31 changes: 0 additions & 31 deletions .github/workflows/firebase-deploy.yml

This file was deleted.

4 changes: 0 additions & 4 deletions .github/workflows/pr.yml
Expand Up @@ -58,10 +58,6 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
- uses: actions/setup-java@v3 # needed to run firebase emulator for firebase unit tests
with:
java-version: '11'
distribution: 'temurin'
- uses: nrwl/nx-set-shas@v2
with:
main-branch-name: master
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -61,3 +61,5 @@ testem.log
Thumbs.db

.parcel-cache

.turbo
7 changes: 6 additions & 1 deletion DEV.md
Expand Up @@ -74,4 +74,9 @@ https://github.com/firebase/firebase-tools/issues/1289
.coverage-expr[title^="Error"] {
background: red;
}
```
```

docker build --platform=linux/amd64 -t test-demo .
docker run -p 3000:3000 test-demo

### Adding resolution for `oauth` package to fix [this issue](https://github.com/jaredhanson/passport-google-oauth2/issues/87) as the passport-google-oauth20 uses an older version with the issue
57 changes: 57 additions & 0 deletions Dockerfile
@@ -0,0 +1,57 @@
FROM node:18.14-alpine3.16 AS builder
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed
RUN apk add --no-cache libc6-compat
RUN apk update
# Set working directory
WORKDIR /app
RUN yarn global add turbo
COPY . .
RUN turbo prune --scope=@altairgraphql/api --docker

# ===

# Add lockfile and package.json's of isolated subworkspace
FROM node:18.14-alpine3.16 AS installer
RUN apk add --no-cache libc6-compat
RUN apk add --no-cache python3 make g++
RUN apk update
WORKDIR /app

# First install dependencies (as they change less often)
COPY .gitignore .gitignore
# we need full instead of json because of the prepare scripts which build?
COPY --from=builder /app/out/full/ .
COPY --from=builder /app/out/yarn.lock ./yarn.lock
COPY turbo.json turbo.json
COPY nx.json nx.json
COPY tsconfig.json tsconfig.json
RUN yarn install
RUN yarn --cwd packages/altair-db prisma migrate deploy

# Build the project and its dependencies
# COPY --from=builder /app/out/full/ .
# COPY turbo.json turbo.json

RUN yarn turbo run build --filter=@altairgraphql/api...

# ===

FROM node:18.14-alpine3.16 AS runner
WORKDIR /app


ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

ARG PORT=3000
ENV PORT=${PORT}

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nodejs
USER nodejs
COPY --from=installer /app .

# EXPOSE ${PORT}

CMD ["node", "packages/altair-api/dist/main"]
1 change: 0 additions & 1 deletion Procfile

This file was deleted.

7 changes: 0 additions & 7 deletions app.json

This file was deleted.

4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -27,7 +27,7 @@
"build:ci": "lerna bootstrap -- --frozen-lockfile",
"lerna-publish": "lerna publish from-git --force-publish=* --yes",
"local-verify": "yarn build-app && lerna bootstrap",
"postinstall": "opencollective postinstall",
"postinstall": "opencollective postinstall || true",
"prepare": "nx run-many --target=prepare --all --output-style=stream",
"publish-packages": "lerna bootstrap && yarn lerna-publish",
"snyk-protect": "snyk protect",
Expand Down Expand Up @@ -62,11 +62,13 @@
"start-server-and-test": "1.11.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.1.0",
"turbo": "^1.7.3",
"typescript": "^4.7.4",
"web-ext": "^6.5.0",
"wrangler": "^2.0.27"
},
"resolutions": {
"**/oauth": "0.10.0",
"y18n": "4.0.1"
},
"repository": {
Expand Down
51 changes: 45 additions & 6 deletions packages/altair-api-utils/src/client.ts
@@ -1,5 +1,8 @@
import { APIClientOptions, ClientEnvironment, getClientConfig } from './config';
import { OAUTH_POPUP_CALLBACK_MESSAGE_TYPE } from './constants';
import {
ALTAIR_API_USER_TOKEN_STORAGE_KEY,
OAUTH_POPUP_CALLBACK_MESSAGE_TYPE,
} from './constants';
import ky from 'ky';
import { KyInstance } from 'ky/distribution/types/ky';
import {
Expand All @@ -16,7 +19,7 @@ import {
} from '@altairgraphql/db';
import { UserProfile } from './user';
import { CreateTeamDto, CreateTeamMembershipDto, UpdateTeamDto } from './team';
import { from, Observable } from 'rxjs';
import { from, Observable, Subject } from 'rxjs';
import { map, switchMap, take } from 'rxjs/operators';
export type FullQueryCollection = QueryCollection & {
queries: QueryItem[];
Expand All @@ -38,18 +41,48 @@ const timeout = <T>(
export class APIClient {
ky: KyInstance;
authToken?: string;
user?: UserProfile;

user$ = new Subject<UserProfile>();
private _user?: UserProfile;
get user() {
return this._user;
}
set user(val) {
this._user = val;
this.user$.next(val);
}

constructor(public options: APIClientOptions) {
// TODO: Check for user access token in local storage
// const userInfoText = localStorage.getItem('ALTAIR-API-USER-INFO');
// this.user = userInfoText ? JSON.parse(userInfoText) : undefined;
this.ky = ky.extend({
prefixUrl: options.apiBaseUrl,
hooks: {
beforeRequest: [req => this.setAuthHeaderBeforeRequest(req)],
},
});

// Check for user access token in local storage
const cachedToken = this.getCachedToken();
if (cachedToken) {
this.signInWithCustomToken(cachedToken).catch(() => {
this.signOut();
});
}
}

private setCachedToken(token: string) {
if (typeof window !== 'undefined') {
window.localStorage.setItem(ALTAIR_API_USER_TOKEN_STORAGE_KEY, token);
}
}
private getCachedToken() {
if (typeof window !== 'undefined') {
return window.localStorage.getItem(ALTAIR_API_USER_TOKEN_STORAGE_KEY);
}
}
private clearCachedToken() {
if (typeof window !== 'undefined') {
window.localStorage.removeItem(ALTAIR_API_USER_TOKEN_STORAGE_KEY);
}
}

private setAuthHeaderBeforeRequest(req: Request) {
Expand All @@ -75,11 +108,16 @@ export class APIClient {
return url.href;
}

observeUser() {
return this.user$.asObservable();
}

async getUser() {
return this.user;
}
async signInWithCustomToken(token: string) {
this.authToken = token;
this.setCachedToken(token);

const user = await this.ky.get('auth/me').json<UserProfile>();

Expand Down Expand Up @@ -133,6 +171,7 @@ export class APIClient {
signOut() {
this.authToken = undefined;
this.user = undefined;
this.clearCachedToken();
}

createQuery(queryInput: CreateQueryDto) {
Expand Down
4 changes: 2 additions & 2 deletions packages/altair-api-utils/src/config.ts
Expand Up @@ -7,8 +7,8 @@ export const getClientConfig = (env: ClientEnvironment = 'development') => {
switch (env) {
case 'production':
return {
apiBaseUrl: 'http://localhost:3000',
loginClientUrl: 'http://localhost:1234',
apiBaseUrl: 'https://api.altairgraphql.dev',
loginClientUrl: 'http://redir.altairgraphql.dev',
};
}

Expand Down
2 changes: 1 addition & 1 deletion packages/altair-api-utils/src/constants.ts
@@ -1,4 +1,4 @@
export const OAUTH_POPUP_CALLBACK_MESSAGE_TYPE =
'altairgql:oauth:callback:response';

export const ALTAIR_API_USER_INFO_STORAGE_KEY = 'ALTAIR-API-USER-INFO';
export const ALTAIR_API_USER_TOKEN_STORAGE_KEY = 'ALTAIR-API-USER-TOKEN';
2 changes: 1 addition & 1 deletion packages/altair-api/.env.example
Expand Up @@ -5,4 +5,4 @@ GOOGLE_OAUTH_CLIENT_SECRET=
POSTGRES_DB=
POSTGRES_USER=
POSTGRES_PASSWORD=
PRISMA_DATABASE_URL=
DATABASE_URL=
3 changes: 1 addition & 2 deletions packages/altair-api/package.json
Expand Up @@ -8,14 +8,13 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"prepare": "yarn build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"env": "sync-dotenv",
"nest:generate:resource": "nest g resource",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main.js",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
Expand Down
20 changes: 15 additions & 5 deletions packages/altair-api/src/auth/auth.controller.ts
@@ -1,4 +1,11 @@
import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
import {
BadRequestException,
Controller,
Get,
Req,
Res,
UseGuards,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Request, Response } from 'express';
import { AuthService } from './auth.service';
Expand All @@ -23,10 +30,13 @@ export class AuthController {
googleSigninCallback(@Req() req: Request, @Res() res: Response) {
const result = this.authService.googleLogin(req);
if (req.query.state && typeof req.query.state === 'string') {
const origin = new URL(req.query.state);
origin.searchParams.set('access_token', result.tokens.accessToken);

return res.redirect(origin.href);
try {
const origin = new URL(req.query.state);
origin.searchParams.set('access_token', result.tokens.accessToken);
return res.redirect(origin.href);
} catch (err) {
throw new BadRequestException('Invalid state provided');
}
}

return res.redirect('https://altairgraphql.dev');
Expand Down
2 changes: 1 addition & 1 deletion packages/altair-api/src/common/config.ts
@@ -1,6 +1,6 @@
const config = {
nest: {
port: 5000,
port: 3000,
},
cors: {
enabled: true,
Expand Down
4 changes: 3 additions & 1 deletion packages/altair-api/src/main.ts
Expand Up @@ -42,6 +42,8 @@ async function bootstrap() {
app.enableCors();
}

await app.listen(process.env.PORT || nestConfig.port);
const port = process.env.PORT || nestConfig.port;
console.log('Listening on port', port);
await app.listen(port);
}
bootstrap();
Expand Up @@ -23,7 +23,9 @@
<ng-container
*ngIf="account?.loggedIn"
>
<h3><app-icon name="flask-conical"></app-icon> {{ 'ACCOUNT_TITLE' | translate }} (Alpha)</h3>
<h3>
<app-icon name="flask-conical"></app-icon> {{ 'ACCOUNT_TITLE' | translate }} (Alpha)
</h3>
<p>Hello, {{ account?.firstName }}</p>
<p>
<a target="_blank" href="https://dash.altairgraphql.dev">
Expand All @@ -38,13 +40,12 @@ <h3><app-icon name="flask-conical"></app-icon> {{ 'ACCOUNT_TITLE' | translate }}
{{ 'LOGOUT_TEXT' | translate }}
</button>
</ng-container>
<nz-collapse style="margin-top: 10px;">
<nz-collapse-panel
[nzHeader]="'Subscribe to the newsletter'"
>
<iframe src="https://altairgraphql.substack.com/embed" width="480" height="320" style="border:1px solid #EEE; background:var(--theme-bg-color);" frameborder="0" scrolling="no"></iframe>
</nz-collapse-panel>
</nz-collapse>
<p>
<a target="_blank" href="https://altairgraphql.substack.com">
Subscribe to the newsletter
<app-icon name="external-link"></app-icon>
</a>
</p>
</div>
</div>
</ng-template>
Expand Down
2 changes: 1 addition & 1 deletion packages/altair-db/prisma/schema.prisma
Expand Up @@ -7,7 +7,7 @@ generator client {

datasource db {
provider = "postgresql"
url = env("PRISMA_DATABASE_URL")
url = env("DATABASE_URL")
}

model QueryItem {
Expand Down