├── .github
└── ISSUE_TEMPLATE
│ ├── bug.md
│ ├── feature-request.md
│ └── question.md
├── .gitignore
├── .vscode
└── launch.json
├── Dockerfile.chummy-builder
├── LICENSE
├── README.md
├── SECURITY.md
├── buildspec.yml
├── chummy.code-workspace
└── extension
├── .babelrc
├── .commitlintrc.js
├── .eslintignore
├── .eslintrc
├── .firebaserc
├── .graphqlconfig.yml
├── .prettierignore
├── .prettierrc
├── .version
├── .versionrc.js
├── .vscode
└── settings.json
├── CHANGELOG.md
├── amplify
├── .config
│ └── project-config.json
├── backend
│ ├── api
│ │ ├── chummy
│ │ │ ├── build
│ │ │ │ ├── cloudformation-template.json
│ │ │ │ ├── parameters.json
│ │ │ │ ├── pipelineFunctions
│ │ │ │ │ ├── InvokeChummyCheckoutTriggerLambdaDataSource.req.vtl
│ │ │ │ │ └── InvokeChummyCheckoutTriggerLambdaDataSource.res.vtl
│ │ │ │ ├── resolvers
│ │ │ │ │ ├── Mutation.cancelSubscription.req.vtl
│ │ │ │ │ ├── Mutation.cancelSubscription.res.vtl
│ │ │ │ │ ├── Mutation.createBookmark.req.vtl
│ │ │ │ │ ├── Mutation.createBookmark.res.vtl
│ │ │ │ │ ├── Mutation.createUser.req.vtl
│ │ │ │ │ ├── Mutation.createUser.res.vtl
│ │ │ │ │ ├── Mutation.deleteBookmark.req.vtl
│ │ │ │ │ ├── Mutation.deleteBookmark.res.vtl
│ │ │ │ │ ├── Mutation.deleteUser.req.vtl
│ │ │ │ │ ├── Mutation.deleteUser.res.vtl
│ │ │ │ │ ├── Mutation.syncUser.req.vtl
│ │ │ │ │ ├── Mutation.syncUser.res.vtl
│ │ │ │ │ ├── Mutation.updateBookmark.req.vtl
│ │ │ │ │ ├── Mutation.updateBookmark.res.vtl
│ │ │ │ │ ├── Mutation.updateUser.req.vtl
│ │ │ │ │ ├── Mutation.updateUser.res.vtl
│ │ │ │ │ ├── Query.getBookmark.req.vtl
│ │ │ │ │ ├── Query.getBookmark.res.vtl
│ │ │ │ │ ├── Query.getUser.req.vtl
│ │ │ │ │ ├── Query.getUser.res.vtl
│ │ │ │ │ ├── Query.listBookmarks.req.vtl
│ │ │ │ │ ├── Query.listBookmarks.res.vtl
│ │ │ │ │ ├── Query.listUsers.req.vtl
│ │ │ │ │ ├── Query.listUsers.res.vtl
│ │ │ │ │ ├── Subscription.onCreateBookmark.req.vtl
│ │ │ │ │ ├── Subscription.onCreateBookmark.res.vtl
│ │ │ │ │ ├── Subscription.onCreateUser.req.vtl
│ │ │ │ │ ├── Subscription.onCreateUser.res.vtl
│ │ │ │ │ ├── Subscription.onDeleteBookmark.req.vtl
│ │ │ │ │ ├── Subscription.onDeleteBookmark.res.vtl
│ │ │ │ │ ├── Subscription.onDeleteUser.req.vtl
│ │ │ │ │ ├── Subscription.onDeleteUser.res.vtl
│ │ │ │ │ ├── Subscription.onUpdateBookmark.req.vtl
│ │ │ │ │ ├── Subscription.onUpdateBookmark.res.vtl
│ │ │ │ │ ├── Subscription.onUpdateUser.req.vtl
│ │ │ │ │ ├── Subscription.onUpdateUser.res.vtl
│ │ │ │ │ ├── User.bookmarks.req.vtl
│ │ │ │ │ └── User.bookmarks.res.vtl
│ │ │ │ ├── schema.graphql
│ │ │ │ └── stacks
│ │ │ │ │ ├── Bookmark.json
│ │ │ │ │ ├── ConnectionStack.json
│ │ │ │ │ ├── CustomResources.json
│ │ │ │ │ ├── FunctionDirectiveStack.json
│ │ │ │ │ └── User.json
│ │ │ ├── parameters.json
│ │ │ ├── schema.graphql
│ │ │ ├── stacks
│ │ │ │ └── CustomResources.json
│ │ │ └── transform.conf.json
│ │ └── chummyRestApi
│ │ │ ├── api-params.json
│ │ │ ├── chummyRestApi-cloudformation-template.json
│ │ │ └── parameters.json
│ ├── auth
│ │ └── chummy9948bcd5
│ │ │ ├── chummy9948bcd5-cloudformation-template.yml
│ │ │ └── parameters.json
│ ├── backend-config.json
│ ├── function
│ │ ├── chummyLambdaLayer
│ │ │ ├── chummyLambdaLayer-awscloudformation-template.json
│ │ │ ├── layer-runtimes.json
│ │ │ ├── lib
│ │ │ │ └── nodejs
│ │ │ │ │ ├── package-lock.json
│ │ │ │ │ └── package.json
│ │ │ └── parameters.json
│ │ ├── chummyPostAuthTrigger
│ │ │ ├── amplify.state
│ │ │ ├── chummyPostAuthTrigger-cloudformation-template.json
│ │ │ ├── function-parameters.json
│ │ │ ├── parameters.json
│ │ │ └── src
│ │ │ │ ├── event.json
│ │ │ │ ├── index.js
│ │ │ │ ├── package-lock.json
│ │ │ │ ├── package.json
│ │ │ │ ├── queries.js
│ │ │ │ └── util.js
│ │ └── chummyServer
│ │ │ ├── amplify.state
│ │ │ ├── chummyServer-cloudformation-template.json
│ │ │ ├── function-parameters.json
│ │ │ ├── parameters.json
│ │ │ └── src
│ │ │ ├── app.js
│ │ │ ├── event.json
│ │ │ ├── index.js
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ ├── queries.js
│ │ │ └── util.js
│ └── tags.json
├── cli.json
└── team-provider-info.json
├── cypress.json
├── cypress
├── fixtures
│ ├── bookmarks.json
│ ├── repositories.json
│ ├── store.json
│ └── user.json
├── integration
│ └── pages.spec.js
├── mock
│ └── api.js
├── plugins
│ └── index.js
├── support
│ ├── commands.js
│ └── index.js
└── utils
│ ├── http.js
│ └── index.js
├── firebase.json
├── manifest-base.json
├── package.json
├── public
├── icon
│ ├── chummy128.png
│ ├── chummy16.png
│ ├── chummy256.png
│ ├── chummy32.png
│ ├── chummy512.png
│ └── chummy64.png
├── index.html
└── social
│ └── social1200_628.png
├── scripts
├── BACKUP.prepublish.sh
├── download.sh
├── localpublish.sh
├── promote.dev.sh
├── promote.gamma.sh
├── promote.prod.sh
└── publish.sh
├── src
├── background
│ ├── app.js
│ ├── constants.ts
│ ├── dao.js
│ ├── index.html
│ ├── index.js
│ ├── redirect.inject.js
│ ├── signin.inject.js
│ ├── storage.js
│ ├── style.inject.js
│ ├── throttling.util.js
│ ├── url-parser.util.js
│ └── util.js
├── components
│ ├── Buttons
│ │ ├── IconAndTextButton.js
│ │ ├── IconButton.js
│ │ └── TextButton.js
│ ├── Containers
│ │ ├── Center.js
│ │ └── ExtensionRootContainer.js
│ ├── ExternalLink.js
│ ├── Form
│ │ ├── Input.js
│ │ ├── Select.js
│ │ └── index.js
│ ├── Icon
│ │ ├── IconWithBadge.js
│ │ ├── IconWithSubIcon.js
│ │ ├── Icons.js
│ │ └── index.js
│ ├── Image
│ │ ├── CircleImage.js
│ │ └── index.js
│ ├── Loading
│ │ ├── Spinner.js
│ │ └── SplashSpinner.js
│ ├── Node
│ │ ├── Base.style.js
│ │ ├── Bookmark.js
│ │ ├── BookmarkRepoNode.js
│ │ ├── File.js
│ │ ├── Folder.js
│ │ ├── RepoNode.js
│ │ ├── SearchResultFileNode.js
│ │ ├── SearchResultMatchNode.js
│ │ ├── Tab.js
│ │ ├── TreeOrBlobNode.js
│ │ └── util.js
│ ├── OpenCloseChevron.js
│ ├── Panel
│ │ ├── index.js
│ │ └── style.js
│ ├── ResizableSidebar
│ │ ├── ActionButtons
│ │ │ ├── Collapse.js
│ │ │ ├── DistractionFreeMode.js
│ │ │ └── util.js
│ │ ├── index.js
│ │ ├── style.js
│ │ └── util.js
│ ├── Scrollbars.js
│ ├── Section
│ │ ├── SplitSections.js
│ │ └── index.js
│ ├── Text
│ │ └── index.js
│ └── Toast
│ │ ├── Container.js
│ │ └── Toast.js
├── config
│ ├── browser.js
│ ├── dao
│ │ ├── index.js
│ │ └── queries.js
│ ├── log.js
│ ├── octokit
│ │ ├── index.js
│ │ └── queries.js
│ ├── routes.js
│ ├── store
│ │ ├── I.file.store.ts
│ │ ├── I.root.store.ts
│ │ ├── I.ui.store.ts
│ │ ├── I.user.store.ts
│ │ ├── constants.ts
│ │ ├── context.ts
│ │ ├── file.store.ts
│ │ ├── root.store.ts
│ │ ├── ui.store.ts
│ │ ├── user.store.ts
│ │ └── util.ts
│ └── theme
│ │ ├── context.js
│ │ ├── fonts.css
│ │ ├── global.style.js
│ │ ├── selector.js
│ │ ├── themes.js
│ │ └── utils.js
├── constants
│ ├── colors.js
│ ├── languages.js
│ ├── sizes.js
│ └── theme.js
├── content-scripts
│ ├── index.js
│ └── util.js
├── global
│ ├── constants.ts
│ ├── errors
│ │ ├── index.js
│ │ ├── throttling.error.js
│ │ ├── user.error.js
│ │ └── window.error.js
│ └── limits
│ │ ├── constants.ts
│ │ ├── features.js
│ │ └── operations.js
├── graphql
│ ├── mutations.js
│ ├── queries.js
│ └── subscriptions.js
├── hooks
│ ├── dao.js
│ ├── getFolderFiles.js
│ ├── octokit.js
│ ├── store.js
│ ├── useBookmarkState.js
│ ├── useDebounce.js
│ ├── useDimension.js
│ ├── usePrevious.js
│ ├── useTheme.js
│ └── useWindowSize.js
├── options
│ ├── index.html
│ └── index.js
├── pages
│ ├── Account
│ │ ├── SignIn.js
│ │ ├── Signin.style.js
│ │ └── index.js
│ ├── App
│ │ └── index.js
│ ├── Bookmarks
│ │ ├── index.js
│ │ └── util.js
│ ├── Notifications
│ │ └── index.js
│ ├── Search
│ │ ├── LanguagesSelect.js
│ │ └── index.js
│ ├── Settings
│ │ ├── index.js
│ │ └── options.js
│ ├── Tree
│ │ ├── Files.js
│ │ ├── OpenTabs.js
│ │ └── index.js
│ └── Vcs
│ │ └── index.js
├── popup
│ ├── index.html
│ └── index.js
├── themes
│ ├── dracula.dark.json
│ ├── janestheme.light.json
│ ├── material.dark.json
│ ├── material.light.json
│ ├── monokai.dark.json
│ ├── onedark.dark.json
│ ├── vanilla.dark.json
│ └── vanilla.light.json
└── utils
│ ├── bookmark.js
│ ├── browser.js
│ ├── index.js
│ ├── repository.js
│ ├── tabs.js
│ ├── throttling.js
│ └── user.js
├── tsconfig.json
├── webpack
├── BACKUP.prod.web.config.js
├── dev.base.config.js
├── dev.moz.config.js
├── dev.web.config.js
├── gamma.moz.config.js
├── gamma.web.cloud.config.js
├── gamma.web.config.js
├── prod.base.config.js
├── prod.chrome.config.js
├── prod.edge.config.js
├── prod.moz.config.js
├── prod.opera.config.js
├── prod.web.config.js
└── util.js
└── yarn.lock
/.github/ISSUE_TEMPLATE/bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug
3 | about: "I spy a bug \U0001F41E"
4 | title: '[BUG] '
5 | labels: bug-report
6 | assignees: ''
7 | ---
8 |
9 | ### Version Information
10 |
11 | | Software | Information |
12 | | ----------------- | --------------------- |
13 | | Browser | (e.g. Chrome, Safari) |
14 | | Browser Version | (e.g. 22) |
15 | | Extension Version | (e.g. 0.1.0) |
16 |
17 | ### What is the expected behavior?
18 |
19 | ### What is the actual behavior?
20 |
21 | ### Screenshot or animated gif
22 |
23 | You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
24 |
25 | ### Other notes on how to reproduce the issue?
26 |
27 | ### Any possible solutions?
28 |
29 | ### If the bug is confirmed, would you be willing to submit a PR?
30 |
31 | Yes / No _(Help can be provided if you need assistance submitting a PR)_
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: "I have an idea \U0001F4A1"
4 | title: '[FEAT] '
5 | labels: feature-request
6 | assignees: ''
7 | ---
8 |
9 | ### Version Information
10 |
11 | | Software | Information |
12 | | ----------------- | --------------------- |
13 | | Browser | (e.g. Chrome, Safari) |
14 | | Browser Version | (e.g. 22) |
15 | | Extension Version | (e.g. 0.1.0) |
16 |
17 | ### Context
18 |
19 | What are you trying to do and how would you want to do it differently? Is it something you currently you cannot do? Is this related to an issue/problem?
20 |
21 | ### Screenshot or animated gif
22 |
23 | You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
24 |
25 | ### Alternatives
26 |
27 | Can you achieve the same result doing it in an alternative way? Is the alternative considerable?
28 |
29 | ### Has the feature been requested before?
30 |
31 | Please provide a link to the issue.
32 |
33 | ### If the feature request is approved, would you be willing to submit a PR?
34 |
35 | Yes / No _(Help can be provided if you need assistance submitting a PR)_
36 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: I need some clarification ❓
4 | title: '[Q] '
5 | labels: question
6 | assignees: ''
7 | ---
8 |
9 | **Before submitting this issue, make sure you've read over the [I Have a Question](https://github.com/AtomicCodeLabs/chummy/blob/master/docs/CONTRIBUTING.md#i-have-a-question) section of the Contributing guidelines.**
10 |
11 | ### Version Information
12 |
13 | | Software | Information |
14 | | ----------------- | --------------------- |
15 | | Browser | (e.g. Chrome, Safari) |
16 | | Browser Version | (e.g. 22) |
17 | | Extension Version | (e.g. 0.1.0) |
18 |
19 | ### Alternatives
20 |
21 | Can you achieve the same result doing it in an alternative way? Is the alternative considerable?
22 |
23 | ### Has this question been asked before?
24 |
25 | Please provide a link to the issue.
26 |
27 | ### Screenshot or animated gif
28 |
29 | You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
30 |
31 | ### If the feature request is approved, would you be willing to submit a PR?
32 |
33 | Yes / No _(Help can be provided if you need assistance submitting a PR)_
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *node_modules*
2 | *.env*
3 | *.pem*
4 | ci/
5 |
6 | # Extension
7 | extension/dist
8 | extension/dist.prod
9 | extension/webpack/reports/**/*
10 | extension/cypress/screenshots
11 | extension/cypress/videos
12 | ## Amplify
13 | extension/amplify-backup
14 | extension/amplify/\#current-cloud-backend
15 | extension/amplify/.config/local-*
16 | extension/amplify/logs
17 | extension/amplify/mock-data
18 | extension/amplify/backend/amplify-meta.json
19 | extension/amplify/backend/awscloudformation
20 | extension/amplify/backend/.temp
21 | extension/src/aws-exports.js
22 | **/awsconfiguration.json
23 | **/amplifyconfiguration.json
24 | **/amplify-build-config.json
25 | **/amplify-gradle-config.json
26 | **/amplifytools.xcconfig
27 | **/.secret-*
28 |
29 | # Website
30 | website/public
31 | website/.cache
32 |
33 | # Mac
34 | .DS_Store
35 | .AppleDouble
36 | .LSOverride
37 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Launch Dev Server",
9 | "request": "launch",
10 | "runtimeExecutable": "yarn",
11 | "cwd": "${workspaceFolder}/extension",
12 | "runtimeArgs": ["dev:web"],
13 | "type": "pwa-node",
14 | "resolveSourceMapLocations": [
15 | "${workspaceFolder}/**",
16 | "!**/node_modules/**"
17 | ]
18 | },
19 | {
20 | "name": "Build",
21 | "request": "launch",
22 | "runtimeExecutable": "yarn",
23 | "cwd": "${workspaceFolder}/extension",
24 | "runtimeArgs": ["build:web"],
25 | "type": "pwa-node",
26 | "resolveSourceMapLocations": [
27 | "${workspaceFolder}/**",
28 | "!**/node_modules/**"
29 | ]
30 | },
31 | {
32 | "name": "Launch Chrome",
33 | "type": "chrome",
34 | "request": "launch",
35 | "port": 9222,
36 | "url": "https://github.com/AtomicCodeLabs/chummy",
37 | "webRoot": "${workspaceFolder}/extension/dist/dev"
38 | },
39 | {
40 | "name": "Attach Chrome",
41 | "type": "chrome",
42 | "request": "attach",
43 | "port": 9222,
44 | "url": "chrome-extension://dagfciopbcdjofghegmkodmhicjpdgbf",
45 | "webRoot": "${workspaceFolder}/extension"
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/Dockerfile.chummy-builder:
--------------------------------------------------------------------------------
1 | FROM node:12.19.0
2 | LABEL AUTHOR=alexkim205
3 |
4 | # Install other prerequisites
5 | RUN apt-get update && \
6 | apt-get install -y \
7 | zip \
8 | unzip
9 |
10 | # Install AWS CLI
11 | RUN apt-get install -y \
12 | python3 \
13 | python3-pip \
14 | python3-setuptools \
15 | groff \
16 | less \
17 | && pip3 install --upgrade pip \
18 | && apt-get clean
19 |
20 | RUN pip3 --no-cache-dir install --upgrade awscli
21 |
22 | # Install Amplify CLI @latest
23 | RUN npm install -g @aws-amplify/cli
24 |
25 | # Install Cypress prerequisites
26 | RUN apt-get update && \
27 | apt-get install -y \
28 | libgtk2.0-0 \
29 | libgtk-3-0 \
30 | libgbm-dev \
31 | libnotify-dev \
32 | libgconf-2-4 \
33 | libnss3 \
34 | libxss1 \
35 | libasound2 \
36 | libxtst6 \
37 | xauth \
38 | xvfb \
39 | firefox-esr
40 |
41 | USER root
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | Please email alexatatomiccode@gmail.com if you find any security vulnerabilities.
6 |
--------------------------------------------------------------------------------
/buildspec.yml:
--------------------------------------------------------------------------------
1 | version: 0.2
2 |
3 | env:
4 | variables:
5 | VERSION: "1.1.2"
6 | WEBSITE_SIGNIN: "signin/"
7 | WEBSITE_REDIRECT: "account/"
8 | parameter-store:
9 | ROOT_ACCESS_KEY_ID: "ROOT_ACCESS_KEY_ID"
10 | ROOT_SECRET_ACCESS_KEY: "ROOT_SECRET_ACCESS_KEY"
11 |
12 | phases:
13 | install:
14 | commands:
15 | - cd extension
16 | - REACTCONFIG="{\"SourceDir\":\"src\",\"DistributionDir\":\"dist\",\"BuildCommand\":\"yarn build:web\",\"StartCommand\":\"yarn dev\"}"
17 | - AWSCLOUDFORMATIONCONFIG="{\"configLevel\":\"project\",\"useProfile\":false,\"profileName\":\"default\",\"accessKeyId\":\"$ROOT_ACCESS_KEY_ID\",\"secretAccessKey\":\"$ROOT_SECRET_ACCESS_KEY\",\"region\":\"$AWS_DEFAULT_REGION\"}"
18 | - AMPLIFY="{\"projectName\":\"chummy\",\"appId\":\"d37x99ddsw850\",\"envName\":\"$STAGE\",\"defaultEditor\":\"code\"}"
19 | - FRONTEND="{\"frontend\":\"javascript\",\"framework\":\"react\",\"config\":$REACTCONFIG}"
20 | - PROVIDERS="{\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG}"
21 | - amplify init --amplify $AMPLIFY --frontend $FRONTEND --providers $PROVIDERS --yes
22 | - echo $CHUMMY_KEY_PEM > ./key.pem
23 | - yarn install --frozen-lockfile
24 | pre_build:
25 | commands:
26 | - yarn lint:check
27 | - yarn format:check
28 | build:
29 | commands:
30 | - yarn build:moz
31 | - yarn build:chrome
32 | - yarn build:edge
33 | - yarn build:opera
34 | post_build:
35 | commands:
36 | - yarn cy:run:moz
37 | - yarn cy:run:chrome
38 | - yarn ci:publish
39 |
40 | artifacts:
41 | base-directory: "extension/dist"
42 | files:
43 | - "**/*"
44 |
45 | cache:
46 | paths:
47 | - "~/.cache"
48 |
--------------------------------------------------------------------------------
/chummy.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "name": "Extension",
5 | "path": "."
6 | },
7 | {
8 | "name": "Website",
9 | "path": "../chummy-web"
10 | },
11 | {
12 | "name": "Docs",
13 | "path": "../chummy-docs"
14 | },
15 | {
16 | "name": "CI",
17 | "path": "../chummy-ci"
18 | },
19 | {
20 | "name": "GitHub Cognito Shim",
21 | "path": "../github-cognito-openid-wrapper"
22 | }
23 | ],
24 | "settings": {},
25 | "launch": {
26 | "configurations": [],
27 | "compounds": [
28 | {
29 | "name": "Dev",
30 | "configurations": [
31 | {
32 | "folder": "Extension",
33 | "name": "Launch Dev Server"
34 | },
35 | {
36 | "folder": "Website",
37 | "name": "Launch Dev Server"
38 | },
39 | {
40 | "folder": "Extension",
41 | "name": "Launch Chrome"
42 | }
43 | ]
44 | }
45 | ]
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/extension/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "useBuiltIns": "usage", // alternative mode: "entry"
7 | "corejs": 3, // default would be 2
8 | "targets": [">0.25%", "not dead", "not ie <= 11", "not op_mini all"]
9 | // set your own target environment here (see Browserslist)
10 | }
11 | ],
12 | "@babel/preset-react"
13 | ],
14 | "plugins": [
15 | [
16 | "@babel/plugin-proposal-decorators",
17 | {
18 | "legacy": true
19 | }
20 | ],
21 | [
22 | "@babel/plugin-proposal-class-properties",
23 | {
24 | "loose": true
25 | }
26 | ],
27 | "@babel/plugin-syntax-dynamic-import",
28 | "@loadable/babel-plugin"
29 | ],
30 | "env": {
31 | "production": {
32 | "plugins": [
33 | [
34 | "transform-react-remove-prop-types",
35 | {
36 | "mode": "wrap",
37 | "ignoreFilenames": ["node_modules"]
38 | }
39 | ],
40 | "minify-constant-folding",
41 | "tailcall-optimization"
42 | ]
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/extension/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parserPreset: 'conventional-changelog-conventionalcommits',
3 | rules: {
4 | 'body-leading-blank': [1, 'always'],
5 | 'body-max-line-length': [2, 'always', 100],
6 | 'footer-leading-blank': [1, 'always'],
7 | 'footer-max-line-length': [2, 'always', 100],
8 | 'header-max-length': [2, 'always', 100],
9 | 'scope-case': [2, 'always', 'lower-case'],
10 | 'subject-case': [
11 | 2,
12 | 'never',
13 | ['sentence-case', 'start-case', 'pascal-case', 'upper-case']
14 | ],
15 | 'subject-empty': [2, 'never'],
16 | 'subject-full-stop': [2, 'never', '.'],
17 | 'type-case': [2, 'always', 'lower-case'],
18 | 'type-empty': [2, 'never'],
19 | 'type-enum': [
20 | 2,
21 | 'always',
22 | [
23 | 'build',
24 | 'chore',
25 | 'ci',
26 | 'docs',
27 | 'feat',
28 | 'fix',
29 | 'perf',
30 | 'refactor',
31 | 'revert',
32 | 'style',
33 | 'test'
34 | ]
35 | ]
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/extension/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | dist/*
3 | dist.prod/*
4 | .vscode/*
5 | github-cognito-openid-wrapper/*
6 | amplify/*
7 | src/aws-exports.js
--------------------------------------------------------------------------------
/extension/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "env": {
4 | "browser": true,
5 | "jest": true,
6 | "es6": true,
7 | "cypress/globals": true
8 | },
9 | "plugins": ["import", "cypress"],
10 | "extends": ["airbnb", "prettier", "prettier/react"],
11 | "parserOptions": {
12 | "ecmaVersion": 2018,
13 | "sourceType": "module"
14 | },
15 | "parser": "babel-eslint",
16 | "rules": {
17 | "import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
18 | "consistent-return": "off",
19 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
20 | "no-console": "off",
21 | "no-eval": "error",
22 | "import/first": "error",
23 | "no-param-reassign": "off",
24 | "import/extensions": [
25 | "error",
26 | "ignorePackages",
27 | {
28 | "js": "never",
29 | "jsx": "never",
30 | "ts": "never",
31 | "tsx": "never"
32 | }
33 | ],
34 | "lines-between-class-members": "off"
35 | },
36 | "settings": {
37 | "import/resolver": {
38 | "typescript": {}
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/extension/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "dev": "chummy-dev-1",
4 | "prod": "chummy-prod-1"
5 | }
6 | }
--------------------------------------------------------------------------------
/extension/.graphqlconfig.yml:
--------------------------------------------------------------------------------
1 | projects:
2 | chummy:
3 | schemaPath: amplify/backend/api/chummy/build/schema.graphql
4 | includes:
5 | - src/graphql/**/*.js
6 | excludes:
7 | - ./amplify/**
8 | extensions:
9 | amplify:
10 | codeGenTarget: javascript
11 | generatedFileName: ''
12 | docsFilePath: src/graphql
13 | extensions:
14 | amplify:
15 | version: 3
16 |
--------------------------------------------------------------------------------
/extension/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | dist/*
3 | dist.prod/*
4 | webpack/reports/*
5 | .vscode/*
6 | github-cognito-openid-wrapper/*
7 | amplify/*
8 | src/aws-exports.js
9 | CHANGELOG.md
--------------------------------------------------------------------------------
/extension/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "trailingComma": "none",
4 | "singleQuote": true,
5 | "printWidth": 80
6 | }
7 |
--------------------------------------------------------------------------------
/extension/.version:
--------------------------------------------------------------------------------
1 | 1.1.2
--------------------------------------------------------------------------------
/extension/.versionrc.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const detectNewline = require('detect-newline');
3 |
4 | const tracker = {
5 | filename: './package.json',
6 | type: 'json'
7 | };
8 |
9 | const buildConfig = {
10 | filename: '../buildspec.yml',
11 | updater: {
12 | readVersion: (contents) => {
13 | const newLine = detectNewline(contents);
14 | return contents.match(new RegExp(`VERSION: "(.*)"${newLine}`)).pop();
15 | },
16 | writeVersion: (contents, version) => {
17 | const newLine = detectNewline(contents);
18 | return contents.replace(
19 | new RegExp(`VERSION: "(.*)"${newLine}`),
20 | `VERSION: "${version}"${newLine}`
21 | );
22 | }
23 | }
24 | };
25 |
26 | const versionFile = {
27 | filename: './.version',
28 | type: 'plain-text'
29 | };
30 |
31 | module.exports = {
32 | bumpFiles: [tracker, buildConfig, versionFile],
33 | packageFiles: [tracker]
34 | };
35 |
--------------------------------------------------------------------------------
/extension/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "amplify/.config": true,
4 | "amplify/**/*-parameters.json": true,
5 | "amplify/**/amplify.state": true,
6 | "amplify/**/transform.conf.json": true,
7 | "amplify/#current-cloud-backend": true,
8 | "amplify/backend/amplify-meta.json": true,
9 | "amplify/backend/awscloudformation": true
10 | }
11 | }
--------------------------------------------------------------------------------
/extension/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ## [1.1.2](https://github.com/AtomicCodeLabs/chummy/compare/v1.1.0...v1.1.2) (2021-03-16)
6 |
7 |
8 | ### Bug Fixes
9 |
10 | * bug where toggling df mode from settings page was noop ([0ed3f8b](https://github.com/AtomicCodeLabs/chummy/commit/0ed3f8b8225f3774bd40b750c91c024e8ab05841))
11 |
12 | ## [1.1.1](https://github.com/AtomicCodeLabs/chummy/compare/v1.1.0...v1.1.1) (2021-03-16)
13 |
14 |
15 | ### Bug Fixes
16 |
17 | * bug where toggling df mode from settings page was noop ([0ed3f8b](https://github.com/AtomicCodeLabs/chummy/commit/0ed3f8b8225f3774bd40b750c91c024e8ab05841))
18 |
19 | ## [1.1.0](https://github.com/AtomicCodeLabs/chummy/compare/v1.0.0...v1.1.0) (2021-03-14)
20 |
21 |
22 | ### Features
23 |
24 | * add janes theme and dracula ([77a9823](https://github.com/AtomicCodeLabs/chummy/commit/77a9823b381cb7923f80a05ede3e2278e15d3548))
25 | * folder collapsing and distraction free mode ([faf9e44](https://github.com/AtomicCodeLabs/chummy/commit/faf9e44ae7b4f08ae127488df00c275a2a99f7a8))
26 |
27 |
28 | ### Bug Fixes
29 |
30 | * fix a few active tab change issues ([3e96922](https://github.com/AtomicCodeLabs/chummy/commit/3e96922aed861bd19d0bf84404d23192ccb98593))
31 | * fix url comparison error that was causing auth bug in prod ([871ef9a](https://github.com/AtomicCodeLabs/chummy/commit/871ef9a8e4ba9792d334aabbf52ec9315641e455))
32 | * user account type updates when subscription changes ([c6177f5](https://github.com/AtomicCodeLabs/chummy/commit/c6177f501bd210d1d9c193e432d6d85b6be61273))
33 |
34 | ## 1.0.0 (2021-02-25)
35 |
36 | The very first iteration of Chummy.
37 |
--------------------------------------------------------------------------------
/extension/amplify/.config/project-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "chummy",
3 | "version": "3.0",
4 | "frontend": "javascript",
5 | "javascript": {
6 | "framework": "react",
7 | "config": {
8 | "SourceDir": "src",
9 | "DistributionDir": "dist",
10 | "BuildCommand": "yarn build:web",
11 | "StartCommand": "yarn dev"
12 | }
13 | },
14 | "providers": [
15 | "awscloudformation"
16 | ]
17 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "CreateAPIKey": 1,
3 | "AppSyncApiName": "chummy",
4 | "DynamoDBBillingMode": "PAY_PER_REQUEST",
5 | "DynamoDBEnableServerSideEncryption": false,
6 | "AuthCognitoUserPoolId": {
7 | "Fn::GetAtt": [
8 | "authchummy9948bcd5",
9 | "Outputs.UserPoolId"
10 | ]
11 | },
12 | "S3DeploymentBucket": "amplify-chummy-dev-213651-deployment",
13 | "S3DeploymentRootKey": "amplify-appsync-files/c835c2d6f952278a277e295d225c89fdab213b79"
14 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/pipelineFunctions/InvokeChummyCheckoutTriggerLambdaDataSource.req.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Invoke AWS Lambda data source: ChummyCheckoutTriggerLambdaDataSource. **
2 | {
3 | "version": "2018-05-29",
4 | "operation": "Invoke",
5 | "payload": {
6 | "typeName": "$ctx.stash.get("typeName")",
7 | "fieldName": "$ctx.stash.get("fieldName")",
8 | "arguments": $util.toJson($ctx.arguments),
9 | "identity": $util.toJson($ctx.identity),
10 | "source": $util.toJson($ctx.source),
11 | "request": $util.toJson($ctx.request),
12 | "prev": $util.toJson($ctx.prev)
13 | }
14 | }
15 | ## [End] Invoke AWS Lambda data source: ChummyCheckoutTriggerLambdaDataSource. **
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/pipelineFunctions/InvokeChummyCheckoutTriggerLambdaDataSource.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Handle error or return result. **
2 | #if( $ctx.error )
3 | $util.error($ctx.error.message, $ctx.error.type)
4 | #end
5 | $util.toJson($ctx.result)
6 | ## [End] Handle error or return result. **
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.cancelSubscription.req.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Stash resolver specific context.. **
2 | $util.qr($ctx.stash.put("typeName", "Mutation"))
3 | $util.qr($ctx.stash.put("fieldName", "cancelSubscription"))
4 | {}
5 | ## [End] Stash resolver specific context.. **
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.cancelSubscription.res.vtl:
--------------------------------------------------------------------------------
1 | $util.toJson($ctx.prev.result)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.createBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $ctx.error )
2 | $util.error($ctx.error.message, $ctx.error.type)
3 | #else
4 | $util.toJson($ctx.result)
5 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.createUser.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $ctx.error )
2 | $util.error($ctx.error.message, $ctx.error.type)
3 | #else
4 | $util.toJson($ctx.result)
5 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.deleteBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $ctx.error )
2 | $util.error($ctx.error.message, $ctx.error.type)
3 | #else
4 | $util.toJson($ctx.result)
5 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.deleteUser.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $ctx.error )
2 | $util.error($ctx.error.message, $ctx.error.type)
3 | #else
4 | $util.toJson($ctx.result)
5 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.syncUser.req.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Stash resolver specific context.. **
2 | $util.qr($ctx.stash.put("typeName", "Mutation"))
3 | $util.qr($ctx.stash.put("fieldName", "syncUser"))
4 | {}
5 | ## [End] Stash resolver specific context.. **
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.syncUser.res.vtl:
--------------------------------------------------------------------------------
1 | $util.toJson($ctx.prev.result)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.updateBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $ctx.error )
2 | $util.error($ctx.error.message, $ctx.error.type)
3 | #else
4 | $util.toJson($ctx.result)
5 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Mutation.updateUser.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $ctx.error )
2 | $util.error($ctx.error.message, $ctx.error.type)
3 | #else
4 | $util.toJson($ctx.result)
5 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.getBookmark.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "operation": "GetItem",
4 | "key": #if( $modelObjectKey ) $util.toJson($modelObjectKey) #else {
5 | "id": $util.dynamodb.toDynamoDBJson($ctx.args.id)
6 | } #end
7 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.getBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $util.isNullOrEmpty($ctx.result) )
2 | #return
3 | #end
4 | ## [Start] Determine request authentication mode **
5 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
6 | #set( $authMode = "userPools" )
7 | #end
8 | ## [End] Determine request authentication mode **
9 | ## [Start] Check authMode and execute owner/group checks **
10 | #if( $authMode == "userPools" )
11 | ## No Static Group Authorization Rules **
12 |
13 |
14 | ## No Dynamic Group Authorization Rules **
15 |
16 |
17 | ## [Start] Owner Authorization Checks **
18 | #set( $isOwnerAuthorized = $util.defaultIfNull($isOwnerAuthorized, false) )
19 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
20 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.result.owner, []) )
21 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
22 | #if( $util.isList($allowedOwners0) )
23 | #foreach( $allowedOwner in $allowedOwners0 )
24 | #if( $allowedOwner == $identityValue )
25 | #set( $isOwnerAuthorized = true )
26 | #end
27 | #end
28 | #end
29 | #if( $util.isString($allowedOwners0) )
30 | #if( $allowedOwners0 == $identityValue )
31 | #set( $isOwnerAuthorized = true )
32 | #end
33 | #end
34 | ## [End] Owner Authorization Checks **
35 |
36 |
37 | ## [Start] Throw if unauthorized **
38 | #if( !($isStaticGroupAuthorized == true || $isDynamicGroupAuthorized == true || $isOwnerAuthorized == true) )
39 | $util.unauthorized()
40 | #end
41 | ## [End] Throw if unauthorized **
42 | #end
43 | ## [End] Check authMode and execute owner/group checks **
44 |
45 | #if( $ctx.error )
46 | $util.error($ctx.error.message, $ctx.error.type)
47 | #else
48 | $util.toJson($ctx.result)
49 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.getUser.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "operation": "GetItem",
4 | "key": #if( $modelObjectKey ) $util.toJson($modelObjectKey) #else {
5 | "id": $util.dynamodb.toDynamoDBJson($ctx.args.id)
6 | } #end
7 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.getUser.res.vtl:
--------------------------------------------------------------------------------
1 | #if( $util.isNullOrEmpty($ctx.result) )
2 | #return
3 | #end
4 | ## [Start] Determine request authentication mode **
5 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
6 | #set( $authMode = "userPools" )
7 | #end
8 | ## [End] Determine request authentication mode **
9 | ## [Start] Check authMode and execute owner/group checks **
10 | #if( $authMode == "userPools" )
11 | ## No Static Group Authorization Rules **
12 |
13 |
14 | ## No Dynamic Group Authorization Rules **
15 |
16 |
17 | ## [Start] Owner Authorization Checks **
18 | #set( $isOwnerAuthorized = $util.defaultIfNull($isOwnerAuthorized, false) )
19 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
20 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.result.owner, []) )
21 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
22 | #if( $util.isList($allowedOwners0) )
23 | #foreach( $allowedOwner in $allowedOwners0 )
24 | #if( $allowedOwner == $identityValue )
25 | #set( $isOwnerAuthorized = true )
26 | #end
27 | #end
28 | #end
29 | #if( $util.isString($allowedOwners0) )
30 | #if( $allowedOwners0 == $identityValue )
31 | #set( $isOwnerAuthorized = true )
32 | #end
33 | #end
34 | ## [End] Owner Authorization Checks **
35 |
36 |
37 | ## [Start] Throw if unauthorized **
38 | #if( !($isStaticGroupAuthorized == true || $isDynamicGroupAuthorized == true || $isOwnerAuthorized == true) )
39 | $util.unauthorized()
40 | #end
41 | ## [End] Throw if unauthorized **
42 | #end
43 | ## [End] Check authMode and execute owner/group checks **
44 |
45 | #if( $ctx.error )
46 | $util.error($ctx.error.message, $ctx.error.type)
47 | #else
48 | $util.toJson($ctx.result)
49 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.listBookmarks.req.vtl:
--------------------------------------------------------------------------------
1 | #set( $limit = $util.defaultIfNull($context.args.limit, 100) )
2 | #set( $ListRequest = {
3 | "version": "2018-05-29",
4 | "limit": $limit
5 | } )
6 | #if( $context.args.nextToken )
7 | #set( $ListRequest.nextToken = $context.args.nextToken )
8 | #end
9 | #if( $context.args.filter )
10 | #set( $ListRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") )
11 | #end
12 | #if( !$util.isNull($modelQueryExpression)
13 | && !$util.isNullOrEmpty($modelQueryExpression.expression) )
14 | $util.qr($ListRequest.put("operation", "Query"))
15 | $util.qr($ListRequest.put("query", $modelQueryExpression))
16 | #if( !$util.isNull($ctx.args.sortDirection) && $ctx.args.sortDirection == "DESC" )
17 | #set( $ListRequest.scanIndexForward = false )
18 | #else
19 | #set( $ListRequest.scanIndexForward = true )
20 | #end
21 | #else
22 | $util.qr($ListRequest.put("operation", "Scan"))
23 | #end
24 | $util.toJson($ListRequest)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.listBookmarks.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] If not static group authorized, filter items **
12 | #if( !$isStaticGroupAuthorized )
13 | #set( $items = [] )
14 | #foreach( $item in $ctx.result.items )
15 | ## No Dynamic Group Authorization Rules **
16 |
17 |
18 | ## [Start] Owner Authorization Checks **
19 | #set( $isLocalOwnerAuthorized = false )
20 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
21 | #set( $allowedOwners0 = $util.defaultIfNull($item.owner, []) )
22 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
23 | #if( $util.isList($allowedOwners0) )
24 | #foreach( $allowedOwner in $allowedOwners0 )
25 | #if( $allowedOwner == $identityValue )
26 | #set( $isLocalOwnerAuthorized = true )
27 | #end
28 | #end
29 | #end
30 | #if( $util.isString($allowedOwners0) )
31 | #if( $allowedOwners0 == $identityValue )
32 | #set( $isLocalOwnerAuthorized = true )
33 | #end
34 | #end
35 | ## [End] Owner Authorization Checks **
36 |
37 |
38 | #if( ($isLocalDynamicGroupAuthorized == true || $isLocalOwnerAuthorized == true) )
39 | $util.qr($items.add($item))
40 | #end
41 | #end
42 | #set( $ctx.result.items = $items )
43 | #end
44 | ## [End] If not static group authorized, filter items **
45 | #end
46 | ## [End] Check authMode and execute owner/group checks **
47 |
48 | #if( $ctx.error )
49 | $util.error($ctx.error.message, $ctx.error.type)
50 | #else
51 | $util.toJson($ctx.result)
52 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.listUsers.req.vtl:
--------------------------------------------------------------------------------
1 | #set( $limit = $util.defaultIfNull($context.args.limit, 100) )
2 | #set( $ListRequest = {
3 | "version": "2018-05-29",
4 | "limit": $limit
5 | } )
6 | #if( $context.args.nextToken )
7 | #set( $ListRequest.nextToken = $context.args.nextToken )
8 | #end
9 | #if( $context.args.filter )
10 | #set( $ListRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") )
11 | #end
12 | #if( !$util.isNull($modelQueryExpression)
13 | && !$util.isNullOrEmpty($modelQueryExpression.expression) )
14 | $util.qr($ListRequest.put("operation", "Query"))
15 | $util.qr($ListRequest.put("query", $modelQueryExpression))
16 | #if( !$util.isNull($ctx.args.sortDirection) && $ctx.args.sortDirection == "DESC" )
17 | #set( $ListRequest.scanIndexForward = false )
18 | #else
19 | #set( $ListRequest.scanIndexForward = true )
20 | #end
21 | #else
22 | $util.qr($ListRequest.put("operation", "Scan"))
23 | #end
24 | $util.toJson($ListRequest)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Query.listUsers.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] If not static group authorized, filter items **
12 | #if( !$isStaticGroupAuthorized )
13 | #set( $items = [] )
14 | #foreach( $item in $ctx.result.items )
15 | ## No Dynamic Group Authorization Rules **
16 |
17 |
18 | ## [Start] Owner Authorization Checks **
19 | #set( $isLocalOwnerAuthorized = false )
20 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
21 | #set( $allowedOwners0 = $util.defaultIfNull($item.owner, []) )
22 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
23 | #if( $util.isList($allowedOwners0) )
24 | #foreach( $allowedOwner in $allowedOwners0 )
25 | #if( $allowedOwner == $identityValue )
26 | #set( $isLocalOwnerAuthorized = true )
27 | #end
28 | #end
29 | #end
30 | #if( $util.isString($allowedOwners0) )
31 | #if( $allowedOwners0 == $identityValue )
32 | #set( $isLocalOwnerAuthorized = true )
33 | #end
34 | #end
35 | ## [End] Owner Authorization Checks **
36 |
37 |
38 | #if( ($isLocalDynamicGroupAuthorized == true || $isLocalOwnerAuthorized == true) )
39 | $util.qr($items.add($item))
40 | #end
41 | #end
42 | #set( $ctx.result.items = $items )
43 | #end
44 | ## [End] If not static group authorized, filter items **
45 | #end
46 | ## [End] Check authMode and execute owner/group checks **
47 |
48 | #if( $ctx.error )
49 | $util.error($ctx.error.message, $ctx.error.type)
50 | #else
51 | $util.toJson($ctx.result)
52 | #end
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onCreateBookmark.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "payload": {}
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onCreateBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] Owner Authorization Checks **
12 | #set( $isOwnerAuthorized = false )
13 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
14 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
15 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
16 | $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
17 | #if( $util.isList($allowedOwners0) )
18 | #foreach( $allowedOwner in $allowedOwners0 )
19 | #if( $allowedOwner == $identityValue )
20 | #set( $isOwnerAuthorized = true )
21 | #end
22 | #end
23 | #end
24 | #if( $util.isString($allowedOwners0) )
25 | #if( $allowedOwners0 == $identityValue )
26 | #set( $isOwnerAuthorized = true )
27 | #end
28 | #end
29 | ## [End] Owner Authorization Checks **
30 |
31 |
32 | ## [Start] Throw if unauthorized **
33 | #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
34 | $util.unauthorized()
35 | #end
36 | ## [End] Throw if unauthorized **
37 | #end
38 | ## [End] Check authMode and execute owner/group checks **
39 |
40 | $util.toJson(null)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onCreateUser.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "payload": {}
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onCreateUser.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] Owner Authorization Checks **
12 | #set( $isOwnerAuthorized = false )
13 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
14 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
15 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
16 | $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
17 | #if( $util.isList($allowedOwners0) )
18 | #foreach( $allowedOwner in $allowedOwners0 )
19 | #if( $allowedOwner == $identityValue )
20 | #set( $isOwnerAuthorized = true )
21 | #end
22 | #end
23 | #end
24 | #if( $util.isString($allowedOwners0) )
25 | #if( $allowedOwners0 == $identityValue )
26 | #set( $isOwnerAuthorized = true )
27 | #end
28 | #end
29 | ## [End] Owner Authorization Checks **
30 |
31 |
32 | ## [Start] Throw if unauthorized **
33 | #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
34 | $util.unauthorized()
35 | #end
36 | ## [End] Throw if unauthorized **
37 | #end
38 | ## [End] Check authMode and execute owner/group checks **
39 |
40 | $util.toJson(null)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onDeleteBookmark.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "payload": {}
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onDeleteBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] Owner Authorization Checks **
12 | #set( $isOwnerAuthorized = false )
13 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
14 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
15 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
16 | $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
17 | #if( $util.isList($allowedOwners0) )
18 | #foreach( $allowedOwner in $allowedOwners0 )
19 | #if( $allowedOwner == $identityValue )
20 | #set( $isOwnerAuthorized = true )
21 | #end
22 | #end
23 | #end
24 | #if( $util.isString($allowedOwners0) )
25 | #if( $allowedOwners0 == $identityValue )
26 | #set( $isOwnerAuthorized = true )
27 | #end
28 | #end
29 | ## [End] Owner Authorization Checks **
30 |
31 |
32 | ## [Start] Throw if unauthorized **
33 | #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
34 | $util.unauthorized()
35 | #end
36 | ## [End] Throw if unauthorized **
37 | #end
38 | ## [End] Check authMode and execute owner/group checks **
39 |
40 | $util.toJson(null)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onDeleteUser.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "payload": {}
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onDeleteUser.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] Owner Authorization Checks **
12 | #set( $isOwnerAuthorized = false )
13 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
14 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
15 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
16 | $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
17 | #if( $util.isList($allowedOwners0) )
18 | #foreach( $allowedOwner in $allowedOwners0 )
19 | #if( $allowedOwner == $identityValue )
20 | #set( $isOwnerAuthorized = true )
21 | #end
22 | #end
23 | #end
24 | #if( $util.isString($allowedOwners0) )
25 | #if( $allowedOwners0 == $identityValue )
26 | #set( $isOwnerAuthorized = true )
27 | #end
28 | #end
29 | ## [End] Owner Authorization Checks **
30 |
31 |
32 | ## [Start] Throw if unauthorized **
33 | #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
34 | $util.unauthorized()
35 | #end
36 | ## [End] Throw if unauthorized **
37 | #end
38 | ## [End] Check authMode and execute owner/group checks **
39 |
40 | $util.toJson(null)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onUpdateBookmark.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "payload": {}
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onUpdateBookmark.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] Owner Authorization Checks **
12 | #set( $isOwnerAuthorized = false )
13 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
14 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
15 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
16 | $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
17 | #if( $util.isList($allowedOwners0) )
18 | #foreach( $allowedOwner in $allowedOwners0 )
19 | #if( $allowedOwner == $identityValue )
20 | #set( $isOwnerAuthorized = true )
21 | #end
22 | #end
23 | #end
24 | #if( $util.isString($allowedOwners0) )
25 | #if( $allowedOwners0 == $identityValue )
26 | #set( $isOwnerAuthorized = true )
27 | #end
28 | #end
29 | ## [End] Owner Authorization Checks **
30 |
31 |
32 | ## [Start] Throw if unauthorized **
33 | #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
34 | $util.unauthorized()
35 | #end
36 | ## [End] Throw if unauthorized **
37 | #end
38 | ## [End] Check authMode and execute owner/group checks **
39 |
40 | $util.toJson(null)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onUpdateUser.req.vtl:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2018-05-29",
3 | "payload": {}
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/resolvers/Subscription.onUpdateUser.res.vtl:
--------------------------------------------------------------------------------
1 | ## [Start] Determine request authentication mode **
2 | #if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
3 | #set( $authMode = "userPools" )
4 | #end
5 | ## [End] Determine request authentication mode **
6 | ## [Start] Check authMode and execute owner/group checks **
7 | #if( $authMode == "userPools" )
8 | ## No Static Group Authorization Rules **
9 |
10 |
11 | ## [Start] Owner Authorization Checks **
12 | #set( $isOwnerAuthorized = false )
13 | ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
14 | #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
15 | #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
16 | $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
17 | #if( $util.isList($allowedOwners0) )
18 | #foreach( $allowedOwner in $allowedOwners0 )
19 | #if( $allowedOwner == $identityValue )
20 | #set( $isOwnerAuthorized = true )
21 | #end
22 | #end
23 | #end
24 | #if( $util.isString($allowedOwners0) )
25 | #if( $allowedOwners0 == $identityValue )
26 | #set( $isOwnerAuthorized = true )
27 | #end
28 | #end
29 | ## [End] Owner Authorization Checks **
30 |
31 |
32 | ## [Start] Throw if unauthorized **
33 | #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
34 | $util.unauthorized()
35 | #end
36 | ## [End] Throw if unauthorized **
37 | #end
38 | ## [End] Check authMode and execute owner/group checks **
39 |
40 | $util.toJson(null)
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/build/stacks/CustomResources.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "An auto-generated nested stack.",
4 | "Metadata": {},
5 | "Parameters": {
6 | "AppSyncApiId": {
7 | "Type": "String",
8 | "Description": "The id of the AppSync API associated with this project."
9 | },
10 | "AppSyncApiName": {
11 | "Type": "String",
12 | "Description": "The name of the AppSync API",
13 | "Default": "AppSyncSimpleTransform"
14 | },
15 | "env": {
16 | "Type": "String",
17 | "Description": "The environment name. e.g. Dev, Test, or Production",
18 | "Default": "NONE"
19 | },
20 | "S3DeploymentBucket": {
21 | "Type": "String",
22 | "Description": "The S3 bucket containing all deployment assets for the project."
23 | },
24 | "S3DeploymentRootKey": {
25 | "Type": "String",
26 | "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
27 | }
28 | },
29 | "Resources": {
30 | "EmptyResource": {
31 | "Type": "Custom::EmptyResource",
32 | "Condition": "AlwaysFalse"
33 | }
34 | },
35 | "Conditions": {
36 | "HasEnvironmentParameter": {
37 | "Fn::Not": [
38 | {
39 | "Fn::Equals": [
40 | {
41 | "Ref": "env"
42 | },
43 | "NONE"
44 | ]
45 | }
46 | ]
47 | },
48 | "AlwaysFalse": {
49 | "Fn::Equals": [
50 | "true",
51 | "false"
52 | ]
53 | }
54 | },
55 | "Outputs": {
56 | "EmptyOutput": {
57 | "Description": "An empty output. You may delete this if you have at least one resource above.",
58 | "Value": ""
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "AppSyncApiName": "chummy",
3 | "DynamoDBBillingMode": "PAY_PER_REQUEST",
4 | "DynamoDBEnableServerSideEncryption": false,
5 | "AuthCognitoUserPoolId": {
6 | "Fn::GetAtt": [
7 | "authchummy9948bcd5",
8 | "Outputs.UserPoolId"
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/schema.graphql:
--------------------------------------------------------------------------------
1 | type User
2 | @model
3 | @auth(
4 | rules: [
5 | {
6 | allow: owner
7 | ownerField: "owner"
8 | operations: [create, update, delete, read]
9 | }
10 | { allow: public, provider: apiKey }
11 | ]
12 | ) {
13 | id: ID!
14 | accountType: String!
15 | bookmarks: [Bookmark] @connection(keyName: "byUser", fields: ["owner"])
16 | metadata: UserMetadata
17 | owner: String!
18 | onMailingList: String
19 | isTrial: String
20 | }
21 |
22 | type UserMetadata {
23 | cognitoUsername: String
24 | cognitoUserPoolId: String
25 | stripeId: String
26 | }
27 |
28 | type Bookmark
29 | @model
30 | @auth(
31 | rules: [
32 | {
33 | allow: owner
34 | ownerField: "owner"
35 | operations: [create, update, delete, read]
36 | }
37 | { allow: public, provider: apiKey }
38 | ]
39 | )
40 | @key(name: "byUser", fields: ["owner", "name"]) {
41 | id: ID!
42 | userId: ID!
43 | name: String!
44 | path: String!
45 | pinned: String! # We have to use String type because Boolean types can't be sort keys
46 | branch: String!
47 | repo: String!
48 | owner: String!
49 | }
50 |
51 | # Method resolver - https://dev.to/aws-builders/use-lambda-resolvers-in-your-graphql-api-with-aws-amplify-5e13
52 | type Mutation {
53 | cancelSubscription: CancelSubscriptionResponse
54 | @function(name: "chummyCheckoutTrigger-${env}")
55 | syncUser: SyncUserResponse @function(name: "chummyCheckoutTrigger-${env}")
56 | }
57 |
58 | type CancelSubscriptionResponse {
59 | id: String!
60 | }
61 |
62 | type SyncUserResponse {
63 | id: String!
64 | }
65 |
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/stacks/CustomResources.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "An auto-generated nested stack.",
4 | "Metadata": {},
5 | "Parameters": {
6 | "AppSyncApiId": {
7 | "Type": "String",
8 | "Description": "The id of the AppSync API associated with this project."
9 | },
10 | "AppSyncApiName": {
11 | "Type": "String",
12 | "Description": "The name of the AppSync API",
13 | "Default": "AppSyncSimpleTransform"
14 | },
15 | "env": {
16 | "Type": "String",
17 | "Description": "The environment name. e.g. Dev, Test, or Production",
18 | "Default": "NONE"
19 | },
20 | "S3DeploymentBucket": {
21 | "Type": "String",
22 | "Description": "The S3 bucket containing all deployment assets for the project."
23 | },
24 | "S3DeploymentRootKey": {
25 | "Type": "String",
26 | "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
27 | }
28 | },
29 | "Resources": {
30 | "EmptyResource": {
31 | "Type": "Custom::EmptyResource",
32 | "Condition": "AlwaysFalse"
33 | }
34 | },
35 | "Conditions": {
36 | "HasEnvironmentParameter": {
37 | "Fn::Not": [
38 | {
39 | "Fn::Equals": [
40 | {
41 | "Ref": "env"
42 | },
43 | "NONE"
44 | ]
45 | }
46 | ]
47 | },
48 | "AlwaysFalse": {
49 | "Fn::Equals": ["true", "false"]
50 | }
51 | },
52 | "Outputs": {
53 | "EmptyOutput": {
54 | "Description": "An empty output. You may delete this if you have at least one resource above.",
55 | "Value": ""
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummy/transform.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 5,
3 | "ElasticsearchWarning": true
4 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummyRestApi/api-params.json:
--------------------------------------------------------------------------------
1 | {
2 | "paths": [
3 | {
4 | "name": "/",
5 | "lambdaFunction": "chummyServer",
6 | "privacy": {
7 | "open": true
8 | }
9 | }
10 | ],
11 | "resourceName": "chummyRestApi",
12 | "apiName": "chummyRestApi",
13 | "functionArns": [
14 | {
15 | "lambdaFunction": "chummyServer"
16 | }
17 | ],
18 | "privacy": {
19 | "auth": 1,
20 | "unauth": 0,
21 | "authRoleName": "amplify-chummy-dev-213651-authRole",
22 | "unAuthRoleName": "amplify-chummy-dev-213651-unauthRole"
23 | },
24 | "dependsOn": [
25 | {
26 | "category": "function",
27 | "resourceName": "chummyServer",
28 | "attributes": [
29 | "Name",
30 | "Arn"
31 | ]
32 | }
33 | ],
34 | "uuid": "8e42210c"
35 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/api/chummyRestApi/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "authRoleName": {
3 | "Ref": "AuthRoleName"
4 | },
5 | "unauthRoleName": {
6 | "Ref": "UnauthRoleName"
7 | }
8 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/auth/chummy9948bcd5/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "identityPoolName": "chummy9948bcd5_identitypool_9948bcd5",
3 | "allowUnauthenticatedIdentities": false,
4 | "resourceNameTruncated": "chummy9948bcd5",
5 | "userPoolName": "chummy9948bcd5_userpool_9948bcd5",
6 | "autoVerifiedAttributes": [
7 | "email"
8 | ],
9 | "mfaConfiguration": "OFF",
10 | "mfaTypes": [
11 | "SMS Text Message"
12 | ],
13 | "smsAuthenticationMessage": "Your authentication code is {####}",
14 | "smsVerificationMessage": "Your verification code is {####}",
15 | "emailVerificationSubject": "Your verification code",
16 | "emailVerificationMessage": "Your verification code is {####}",
17 | "defaultPasswordPolicy": false,
18 | "passwordPolicyMinLength": 8,
19 | "passwordPolicyCharacters": [],
20 | "requiredAttributes": [
21 | "email"
22 | ],
23 | "userpoolClientGenerateSecret": true,
24 | "userpoolClientRefreshTokenValidity": 30,
25 | "userpoolClientWriteAttributes": [
26 | "email"
27 | ],
28 | "userpoolClientReadAttributes": [
29 | "email"
30 | ],
31 | "userpoolClientLambdaRole": "chummy9948bcd5_userpoolclient_lambda_role",
32 | "userpoolClientSetAttributes": false,
33 | "sharedId": "9948bcd5",
34 | "resourceName": "chummy9948bcd5",
35 | "authSelections": "identityPoolAndUserPool",
36 | "authRoleArn": {
37 | "Fn::GetAtt": [
38 | "AuthRole",
39 | "Arn"
40 | ]
41 | },
42 | "unauthRoleArn": {
43 | "Fn::GetAtt": [
44 | "UnauthRole",
45 | "Arn"
46 | ]
47 | },
48 | "useDefault": "defaultSocial",
49 | "hostedUI": true,
50 | "hostedUIDomainName": "chummy9948bcd5-9948bcd5",
51 | "authProvidersUserPool": [],
52 | "hostedUIProviderMeta": "[]",
53 | "oAuthMetadata": "{\"AllowedOAuthFlows\":[\"code\"],\"AllowedOAuthScopes\":[\"phone\",\"email\",\"openid\",\"profile\",\"aws.cognito.signin.user.admin\"],\"CallbackURLs\":[\"http://localhost:8000/account/\"],\"LogoutURLs\":[\"http://localhost:8000/\"]}",
54 | "userPoolGroupList": [],
55 | "serviceName": "Cognito",
56 | "usernameCaseSensitive": false,
57 | "dependsOn": []
58 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyLambdaLayer/layer-runtimes.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "nodejs",
4 | "name": "NodeJS",
5 | "layerExecutablePath": "nodejs/node_modules",
6 | "cloudTemplateValue": "nodejs14.x"
7 | }
8 | ]
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyLambdaLayer/lib/nodejs/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "lockfileVersion": 1,
4 | "requires": true,
5 | "dependencies": {
6 | "@types/node": {
7 | "version": "14.14.28",
8 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.28.tgz",
9 | "integrity": "sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g=="
10 | },
11 | "qs": {
12 | "version": "6.9.6",
13 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
14 | "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
15 | },
16 | "stripe": {
17 | "version": "8.135.0",
18 | "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.135.0.tgz",
19 | "integrity": "sha512-cy2IhKhENtvcwdrqtX4jZK4kgu0crA0YrwMgHovIzMAv/Ebr5LqBQ/nhyBqsssExY1hJjn765vhltNrf0WV+Iw==",
20 | "requires": {
21 | "@types/node": ">=8.1.0",
22 | "qs": "^6.6.0"
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyLambdaLayer/lib/nodejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "description": "",
4 | "main": "index.js",
5 | "dependencies": {
6 | "stripe": "^8.135.0"
7 | },
8 | "devDependencies": {}
9 | }
10 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyLambdaLayer/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "layerVersion": 1
3 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/amplify.state:
--------------------------------------------------------------------------------
1 | {
2 | "pluginId": "amplify-nodejs-function-runtime-provider",
3 | "functionRuntime": "nodejs",
4 | "useLegacyBuild": true,
5 | "defaultEditorFile": "src/index.js"
6 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/function-parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "permissions": {
3 | "api": {
4 | "chummy": [
5 | "create",
6 | "read",
7 | "update",
8 | "delete"
9 | ]
10 | },
11 | "storage": {
12 | "User:@model(appsync)": [
13 | "create",
14 | "read",
15 | "update",
16 | "delete"
17 | ],
18 | "Bookmark:@model(appsync)": [
19 | "create",
20 | "read",
21 | "update",
22 | "delete"
23 | ]
24 | }
25 | },
26 | "lambdaLayers": [
27 | {
28 | "type": "ProjectLayer",
29 | "resourceName": "chummyLambdaLayer",
30 | "version": 1
31 | }
32 | ]
33 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/parameters.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/src/event.json:
--------------------------------------------------------------------------------
1 | {
2 | "key1": "value1",
3 | "key2": "value2",
4 | "key3": "value3"
5 | }
6 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/src/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chummyPostAuthTrigger",
3 | "version": "2.0.0",
4 | "lockfileVersion": 1
5 | }
6 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chummyPostAuthTrigger",
3 | "version": "2.0.0",
4 | "description": "Lambda function generated by Amplify",
5 | "main": "index.js",
6 | "license": "Apache-2.0",
7 | "dependencies": {}
8 | }
9 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyPostAuthTrigger/src/queries.js:
--------------------------------------------------------------------------------
1 | const getUser = `query getUser($id: ID!) {
2 | getUser(id: $id) {
3 | id
4 | accountType
5 | metadata {
6 | cognitoUsername
7 | cognitoUserPoolId
8 | stripeId
9 | }
10 | createdAt
11 | updatedAt
12 | owner
13 | bookmarks {
14 | items {
15 | id
16 | userId
17 | name
18 | path
19 | pinned
20 | branch
21 | repo
22 | createdAt
23 | updatedAt
24 | owner
25 | }
26 | }
27 | }
28 | }
29 | `;
30 |
31 | const createUser = `mutation createUser(
32 | $input: CreateUserInput!
33 | $condition: ModelUserConditionInput
34 | ) {
35 | createUser(input: $input, condition: $condition) {
36 | id
37 | accountType
38 | metadata {
39 | cognitoUsername
40 | cognitoUserPoolId
41 | stripeId
42 | }
43 | createdAt
44 | updatedAt
45 | owner
46 | bookmarks {
47 | items {
48 | id
49 | userId
50 | name
51 | path
52 | pinned
53 | branch
54 | repo
55 | createdAt
56 | updatedAt
57 | owner
58 | }
59 | nextToken
60 | }
61 | }
62 | }
63 | `;
64 |
65 | const updateUser = `mutation updateUser(
66 | $input: UpdateUserInput!
67 | $condition: ModelUserConditionInput
68 | ) {
69 | updateUser(input: $input, condition: $condition) {
70 | id
71 | accountType
72 | metadata {
73 | cognitoUsername
74 | cognitoUserPoolId
75 | stripeId
76 | }
77 | createdAt
78 | updatedAt
79 | owner
80 | bookmarks {
81 | items {
82 | id
83 | userId
84 | name
85 | path
86 | pinned
87 | branch
88 | repo
89 | createdAt
90 | updatedAt
91 | owner
92 | }
93 | nextToken
94 | }
95 | }
96 | }
97 | `;
98 |
99 | exports.getUser = getUser;
100 | exports.createUser = createUser;
101 | exports.updateUser = updateUser;
102 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/amplify.state:
--------------------------------------------------------------------------------
1 | {
2 | "pluginId": "amplify-nodejs-function-runtime-provider",
3 | "functionRuntime": "nodejs",
4 | "useLegacyBuild": true,
5 | "defaultEditorFile": "src/app.js"
6 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/function-parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "permissions": {
3 | "api": {
4 | "chummy": [
5 | "create",
6 | "read",
7 | "update",
8 | "delete"
9 | ]
10 | }
11 | },
12 | "lambdaLayers": [
13 | {
14 | "type": "ProjectLayer",
15 | "resourceName": "chummyLambdaLayer",
16 | "version": 1
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/parameters.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/src/event.json:
--------------------------------------------------------------------------------
1 | {
2 | "key1": "value1",
3 | "key2": "value2",
4 | "key3": "value3"
5 | }
6 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/src/index.js:
--------------------------------------------------------------------------------
1 | const awsServerlessExpress = require('aws-serverless-express');
2 | const app = require('./app');
3 |
4 | const server = awsServerlessExpress.createServer(app);
5 |
6 | exports.handler = (event, context) => {
7 | console.log(`EVENT: ${JSON.stringify(event)}`);
8 | return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;
9 | };
10 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chummyServer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "dependencies": {
7 | "aws-serverless-express": "^3.3.5",
8 | "body-parser": "^1.19.0",
9 | "express": "^4.15.2"
10 | },
11 | "devDependencies": {},
12 | "scripts": {
13 | "test": "echo \"Error: no test specified\" && exit 1"
14 | },
15 | "author": "",
16 | "license": "ISC"
17 | }
18 |
--------------------------------------------------------------------------------
/extension/amplify/backend/function/chummyServer/src/queries.js:
--------------------------------------------------------------------------------
1 | const updateUser = `mutation updateUser(
2 | $input: UpdateUserInput!
3 | $condition: ModelUserConditionInput
4 | ) {
5 | updateUser(input: $input, condition: $condition) {
6 | id
7 | accountType
8 | metadata {
9 | cognitoUsername
10 | cognitoUserPoolId
11 | stripeId
12 | }
13 | createdAt
14 | updatedAt
15 | owner
16 | bookmarks {
17 | items {
18 | id
19 | userId
20 | name
21 | path
22 | pinned
23 | branch
24 | repo
25 | createdAt
26 | updatedAt
27 | owner
28 | }
29 | nextToken
30 | }
31 | }
32 | }
33 | `;
34 |
35 | exports.updateUser = updateUser;
36 |
--------------------------------------------------------------------------------
/extension/amplify/backend/tags.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Key": "user:Stack",
4 | "Value": "{project-env}"
5 | },
6 | {
7 | "Key": "user:Application",
8 | "Value": "{project-name}"
9 | }
10 | ]
--------------------------------------------------------------------------------
/extension/amplify/cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "features": {
3 | "graphqltransformer": {
4 | "addmissingownerfields": true,
5 | "validatetypenamereservedwords": true,
6 | "useexperimentalpipelinedtransformer": false,
7 | "enableiterativegsiupdates": false
8 | },
9 | "frontend-ios": {
10 | "enablexcodeintegration": true
11 | },
12 | "auth": {
13 | "enablecaseinsensitivity": true
14 | },
15 | "codegen": {
16 | "useappsyncmodelgenplugin": true
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/extension/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "retries": {
3 | "runMode": 2,
4 | "openMode": 2
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/extension/cypress/fixtures/bookmarks.json:
--------------------------------------------------------------------------------
1 | {
2 | "action": "get-bookmarks",
3 | "payload": {
4 | "bookmarks": [
5 | {
6 | "pinned": false,
7 | "branch": { "name": "master" },
8 | "bookmarkId": "bookmark-alexkim205:chummy:extension/public/icon/up16.png",
9 | "repo": { "name": "chummy", "owner": "alexkim205" },
10 | "path": "extension/public/icon/up16.png",
11 | "name": "up16.png"
12 | },
13 | {
14 | "path": "extension/.babelrc",
15 | "branch": { "name": "master" },
16 | "bookmarkId": "bookmark-alexkim205:chummy:extension/.babelrc",
17 | "name": ".babelrc",
18 | "repo": { "name": "chummy", "owner": "alexkim205" },
19 | "pinned": false
20 | },
21 | {
22 | "branch": { "name": "master" },
23 | "path": ".gitignore",
24 | "pinned": false,
25 | "bookmarkId": "bookmark-alexkim205:DeepSpotify:.gitignore",
26 | "repo": { "name": "DeepSpotify", "owner": "alexkim205" },
27 | "name": ".gitignore"
28 | },
29 | {
30 | "repo": { "owner": "alexkim205", "name": "DeepSpotify" },
31 | "path": "DeepSpotify.yml",
32 | "name": "DeepSpotify.yml",
33 | "bookmarkId": "bookmark-alexkim205:DeepSpotify:DeepSpotify.yml",
34 | "branch": { "name": "master" },
35 | "pinned": false
36 | },
37 | {
38 | "repo": { "name": "G-Desktop-Suite", "owner": "alexkim205" },
39 | "name": "README.md",
40 | "path": "README.md",
41 | "bookmarkId": "bookmark-alexkim205:G-Desktop-Suite:README.md",
42 | "pinned": false,
43 | "branch": { "name": "master" }
44 | },
45 | {
46 | "bookmarkId": "bookmark-alexkim205:chummy:.gitignore",
47 | "name": ".gitignore",
48 | "pinned": false,
49 | "path": ".gitignore",
50 | "repo": { "owner": "alexkim205", "name": "chummy" },
51 | "branch": { "name": "master" }
52 | },
53 | {
54 | "repo": { "name": "chummy", "owner": "alexkim205" },
55 | "path": ".vscode/launch.json",
56 | "pinned": false,
57 | "bookmarkId": "bookmark-alexkim205:chummy:.vscode/launch.json",
58 | "branch": { "name": "master" },
59 | "name": "launch.json"
60 | }
61 | ]
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/extension/cypress/fixtures/repositories.json:
--------------------------------------------------------------------------------
1 | {
2 | "action": "get-open-repositories",
3 | "payload": {
4 | "AtomicCodeLabs/chummy": [
5 | {
6 | "url": "https://github.com/AtomicCodeLabs/chummy",
7 | "owner": "alexkim205",
8 | "repo": "chummy",
9 | "tab": {
10 | "name": "master",
11 | "tabId": 2,
12 | "subpage": "repository",
13 | "nodeName": null
14 | },
15 | "type": "tree"
16 | },
17 | {
18 | "url": "https://github.com/AtomicCodeLabs/chummy",
19 | "owner": "alexkim205",
20 | "repo": "chummy",
21 | "tab": {
22 | "name": "master",
23 | "tabId": 11,
24 | "subpage": "repository",
25 | "nodeName": null
26 | },
27 | "type": "tree"
28 | }
29 | ]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/extension/cypress/fixtures/store.json:
--------------------------------------------------------------------------------
1 | {
2 | "action": "get-store",
3 | "payload": {
4 | "isBookmarksSectionMinimized": true,
5 | "isSearchSectionMinimized": true,
6 | "isSidebarMinimized": false,
7 | "isStickyWindow": false,
8 | "isTreeSectionMinimized": {
9 | "files": { "isMinimized": false, "lastHeight": 722 },
10 | "openTabs": { "isMinimized": false, "lastHeight": 257 },
11 | "sessions": { "isMinimized": true, "lastHeight": 87 }
12 | },
13 | "language": "en_US",
14 | "selectedBookmarkQuery": null,
15 | "selectedBookmarkRepo": null,
16 | "selectedLanguage": null,
17 | "selectedOpenRepo": null,
18 | "selectedQuery": null,
19 | "sidebarView": 0,
20 | "sidebarWidth": 533,
21 | "spacing": "cozy",
22 | "theme": "vanilla-dark"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/extension/cypress/fixtures/user.json:
--------------------------------------------------------------------------------
1 | {
2 | "action": "get-current-user",
3 | "payload": {
4 | "user": {
5 | "uid": "LR3KUY0FumTy4u79tRJEK88YoTj2",
6 | "email": "agk2144@columbia.edu",
7 | "displayName": "Alex Gyujin Kim",
8 | "photoURL": "https://avatars1.githubusercontent.com/u/13460330?v=4",
9 | "apiKey": "292836e915bf829c4f04307e01f91357a701cfd5",
10 | "accountType": null
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/extension/cypress/integration/pages.spec.js:
--------------------------------------------------------------------------------
1 | import mockApi from '../mock/api';
2 |
3 | describe('Render each page', () => {
4 | before('set sidebar viewport', () => {
5 | mockApi();
6 | });
7 |
8 | beforeEach(() => {
9 | cy.viewport(400, 1000);
10 | });
11 |
12 | afterEach(() => {
13 | cy.clearCookies();
14 | });
15 |
16 | describe('Account', () => {
17 | it('page title is `Account`', () => {
18 | cy.goTo('Account');
19 | cy.findById('page-title').should('contain.text', 'Account');
20 | });
21 | });
22 |
23 | describe('Bookmarks', () => {
24 | it('page title is `Bookmarks`', () => {
25 | cy.goTo('Bookmarks');
26 | cy.findById('page-title').should('contain.text', 'Bookmarks');
27 | });
28 | });
29 |
30 | describe('Search', () => {
31 | it('page title is `Search`', () => {
32 | cy.goTo('Search');
33 | cy.findById('page-title').should('contain.text', 'Search');
34 | });
35 | });
36 |
37 | describe('Settings', () => {
38 | it('page title is `Settings`', () => {
39 | cy.goTo('Settings');
40 | cy.findById('page-title').should('contain.text', 'Settings');
41 | });
42 | });
43 |
44 | describe('Tree', () => {
45 | it('page title is `Explorer`', () => {
46 | cy.goTo('Tree');
47 | cy.findById('page-title').should('contain.text', 'Explorer');
48 | });
49 | });
50 |
51 | // describe('VCS', () => {
52 | // it('page title is `Source Control`', () => {
53 | // cy.goTo('VCS');
54 | // // cy.findById('page-title').should('contain.text', 'Source Control');
55 | // });
56 | // });
57 | });
58 |
--------------------------------------------------------------------------------
/extension/cypress/mock/api.js:
--------------------------------------------------------------------------------
1 | import browser from 'sinon-chrome';
2 | import { interceptJS } from '../utils/http';
3 |
4 | export default () => {
5 | browser.runtime.id = 'testid'; // workaround https://github.com/mozilla/webextension-polyfill/issues/218
6 |
7 | interceptJS();
8 |
9 | // Retrieve test data
10 | cy.fixture('user').then((user) => {
11 | cy.fixture('bookmarks').then((bookmarks) => {
12 | cy.fixture('repositories').then((repositories) => {
13 | cy.fixture('store').then((store) => {
14 | browser.runtime.sendMessage
15 | .withArgs({ action: 'get-current-user' })
16 | .yields(user);
17 | browser.runtime.sendMessage
18 | .withArgs({ action: 'get-open-repositories' })
19 | .yields(repositories);
20 | browser.runtime.sendMessage
21 | .withArgs({
22 | action: 'get-store',
23 | payload: Object.keys(store.payload)
24 | })
25 | .yields(store);
26 | browser.runtime.sendMessage
27 | .withArgs({ action: 'get-bookmarks' })
28 | .yields(bookmarks);
29 |
30 | // Load your popup
31 | cy.visit(`popup.html`, {
32 | // If you need to stub `chrome*` API, you should do it there:
33 | onBeforeLoad(win) {
34 | global.chrome = browser;
35 | win.chrome = browser;
36 | }
37 | });
38 | });
39 | });
40 | });
41 | });
42 | };
43 |
--------------------------------------------------------------------------------
/extension/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const extensionLoader = require('cypress-browser-extension-plugin/loader');
3 |
4 | ///
If you've reached this page, Chummy Extension has built successfully.
12 | 13 | 14 | -------------------------------------------------------------------------------- /extension/public/social/social1200_628.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtomicCodeLabs/chummy/5e752bcdbdc3d05c914b504567fdd0084127e707/extension/public/social/social1200_628.png -------------------------------------------------------------------------------- /extension/scripts/BACKUP.prepublish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $CODEBUILD_SRC_DIR/extension/dist 4 | pwd 5 | 6 | VERSION=$(cat ".version") 7 | STAGE=$1 8 | 9 | # Pushing to 10 | for filename in web/{popup_$VERSION,background.dao_$VERSION}*.js; do 11 | echo "Pushing $filename to s3://chummy-assets-$STAGE/$VERSION/" 12 | aws s3 cp $filename s3://chummy-assets-$STAGE/$VERSION/ 13 | done 14 | 15 | cd $CODEBUILD_SRC_DIR/extension 16 | -------------------------------------------------------------------------------- /extension/scripts/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd dist.prod 4 | ls 5 | pwd 6 | 7 | VERSION=$(cat "../.version") 8 | 9 | mkdir $VERSION 10 | cd $VERSION 11 | aws s3 cp s3://chummy-assets-prod/$VERSION/ . --recursive 12 | 13 | cd ../.. 14 | -------------------------------------------------------------------------------- /extension/scripts/localpublish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd dist 4 | ls 5 | pwd 6 | 7 | VERSION=$(cat ".version") 8 | 9 | aws s3 cp gamma.web.cloud/background.dao_$VERSION.js s3://chummy-assets-gamma/$VERSION/ 10 | aws s3 cp gamma.web.cloud/popup_$VERSION.js s3://chummy-assets-gamma/$VERSION/ 11 | 12 | zip -r dist_$VERSION.web.cloud.zip gamma.web.cloud 13 | aws s3 cp dist_$VERSION.web.cloud.zip s3://chummy-assets-gamma/$VERSION/ 14 | 15 | cd .. 16 | -------------------------------------------------------------------------------- /extension/scripts/promote.dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Checkout source branch first 5 | yarn checkout:dev 6 | git add -A 7 | git diff-index --quiet HEAD || HUSKY_SKIP_HOOKS=1 git commit -m "chore(pre-promote): push dev" 8 | git push --follow-tags -u origin extension/dev 9 | 10 | # Push backend 11 | amplify push 12 | -------------------------------------------------------------------------------- /extension/scripts/promote.gamma.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Checkout source branch first 5 | yarn checkout:dev 6 | git add -A 7 | git diff-index --quiet HEAD || HUSKY_SKIP_HOOKS=1 git commit -m "chore(pre-promote): push dev" 8 | git push --follow-tags -u origin extension/dev 9 | 10 | # Checkout target branch 11 | yarn checkout:gamma 12 | git add -A 13 | git diff-index --quiet HEAD || HUSKY_SKIP_HOOKS=1 git commit -m "chore(pre-promote): push gamma" 14 | git push --follow-tags -u origin extension/gamma 15 | 16 | # Merge 17 | HUSKY_SKIP_HOOKS=1 git merge --no-edit -s recursive -X ours extension/dev 18 | 19 | # Push target branch 20 | amplify push 21 | git push --follow-tags -u origin extension/gamma 22 | 23 | # Return to dev branch 24 | yarn checkout:dev 25 | -------------------------------------------------------------------------------- /extension/scripts/promote.prod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Checkout source branch first 5 | yarn checkout:gamma 6 | git add -A 7 | git diff-index --quiet HEAD || HUSKY_SKIP_HOOKS=1 git commit -m "chore(pre-promote): push gamma" 8 | git push --follow-tags -u origin extension/gamma 9 | 10 | # Checkout target branch 11 | yarn checkout:prod 12 | git add -A 13 | git diff-index --quiet HEAD || HUSKY_SKIP_HOOKS=1 git commit -m "chore(pre-promote): push prod" 14 | git push --follow-tags -u origin extension/prod 15 | 16 | # Merge 17 | HUSKY_SKIP_HOOKS=1 git merge --no-edit -s recursive -X ours extension/gamma 18 | 19 | # Push target branch 20 | amplify push 21 | git push --follow-tags -u origin extension/prod 22 | 23 | # Return to dev branch 24 | yarn checkout:dev 25 | -------------------------------------------------------------------------------- /extension/scripts/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $CODEBUILD_SRC_DIR/extension/dist 4 | ls 5 | pwd 6 | 7 | VERSION=$(cat ".version") 8 | STAGE=$1 9 | 10 | zip -r dist_$VERSION.chrome.zip chrome 11 | aws s3 cp dist_$VERSION.chrome.zip s3://chummy-assets-$STAGE/$VERSION/ 12 | 13 | zip -r dist_$VERSION.edge.zip edge 14 | aws s3 cp dist_$VERSION.edge.zip s3://chummy-assets-$STAGE/$VERSION/ 15 | 16 | cd opera 17 | zip -r ../dist_$VERSION.opera.zip . 18 | cd .. 19 | aws s3 cp dist_$VERSION.opera.zip s3://chummy-assets-$STAGE/$VERSION/ 20 | 21 | cd moz 22 | zip -r ../dist_$VERSION.moz.zip . 23 | cd .. 24 | aws s3 cp dist_$VERSION.moz.zip s3://chummy-assets-$STAGE/$VERSION/ 25 | 26 | cd $CODEBUILD_SRC_DIR/extension 27 | -------------------------------------------------------------------------------- /extension/src/background/constants.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable camelcase */ 2 | 3 | export const GITHUB_REGEX = new RegExp( 4 | /^(http|https):\/\/github\.com(\/[^/]+){2,}$/ 5 | ); 6 | 7 | // "G-Desktop-Suite/gsuite.rb at revert-68-code-quality-66-prettify · alexkim205/G-Desktop-Suite" 8 | export const REPO_TITLE_REGEX = new RegExp('(?: at )((?:[^ · ]*))'); 9 | 10 | export const generate_ISSUE_TITLE_REGEX = (issueId: number) => 11 | new RegExp(`^(.*?) · Issue #${issueId}`); 12 | 13 | export const generate_PULL_TITLE_REGEX = (pullId: number) => 14 | new RegExp(`^(.*?) · Pull Request #${pullId}`); 15 | 16 | export const NO_WINDOW_EXTENSION_ID = -1; // -3 if it doesn't exist 17 | 18 | export const MIN_MAIN_WINDOW_WIDTH = 500; 19 | -------------------------------------------------------------------------------- /extension/src/background/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /extension/src/background/redirect.inject.js: -------------------------------------------------------------------------------- 1 | import browser from 'webextension-polyfill'; 2 | // eslint-disable-next-line import/prefer-default-export 3 | const redirectPageListeners = () => { 4 | browser.runtime.onMessage.addListener(function redirectListener(request) { 5 | // Make a ajax redirect request 6 | if (request.action === 'redirect-content-script') { 7 | // Garbage collect event listener (listen at most once) 8 | browser.runtime.onMessage.removeListener(redirectListener); 9 | 10 | const { 11 | payload: { owner, repo, type, branch, nodePath } 12 | } = request; 13 | 14 | // Hack: simulate a click on the repository tag by replacing the href 15 | // with the file to redirect to. This gives us a reliable reference element 16 | // to "click" any time any file is chosen. 17 | const repoLink = document.querySelector( 18 | `[data-pjax='#js-repo-pjax-container'][href='/${owner}/${repo}']` 19 | ); 20 | // If navigated to page that doesn't have clickable repo link (like 404) 21 | // fallback to normal redirect. 22 | if (!repoLink) { 23 | window.location.href = `https://github.com/${owner}/${repo}/${type}/${branch}/${nodePath}`; 24 | } else { 25 | // Sometimes ajax redirect will be treated as a normal redirect by GitHub 26 | repoLink.setAttribute( 27 | 'href', 28 | `/${owner}/${repo}/${type}/${branch}/${nodePath}` 29 | ); 30 | repoLink.click(); 31 | } 32 | } 33 | }); 34 | }; 35 | 36 | redirectPageListeners(); 37 | -------------------------------------------------------------------------------- /extension/src/background/signin.inject.js: -------------------------------------------------------------------------------- 1 | import browser from 'webextension-polyfill'; 2 | 3 | console.log('INJECT SIGNIN'); 4 | 5 | /* 6 | Listen for messages from the page. 7 | If the message was from the page script, show an alert. 8 | */ 9 | function authListener() { 10 | window.addEventListener('message', (event) => { 11 | if (event.source === window && event.data?.action === 'auth-from-page') { 12 | console.log(`Content script received message`, event.data); 13 | 14 | const response = { 15 | action: 'auth-from-content-script', 16 | payload: event.data.payload 17 | }; 18 | console.log('Now sending auth message back to extension', response); 19 | browser.runtime.sendMessage(response); 20 | } 21 | }); 22 | } 23 | 24 | // Initialize listener right away 25 | authListener(); 26 | 27 | // Send message after page has loaded 28 | 29 | // Send message to emit auth to content script on script injection 30 | window.postMessage({ action: 'trigger-send-to-cs' }, '*'); 31 | -------------------------------------------------------------------------------- /extension/src/background/storage.js: -------------------------------------------------------------------------------- 1 | import browser from 'webextension-polyfill'; 2 | import log from '../config/log'; 3 | 4 | // Expose chrome storage API that content script can query 5 | const storeAccessListener = async (request) => { 6 | // Sign In 7 | if (request.action === 'set-store') { 8 | try { 9 | await browser.storage.sync.set(request.payload); 10 | } catch (error) { 11 | log.error('Error setting store', error); 12 | } 13 | return null; 14 | } 15 | 16 | // Sign Out 17 | if (request.action === 'get-store') { 18 | try { 19 | const items = await browser.storage.sync.get(request.payload); 20 | return { action: 'get-store', payload: items }; 21 | } catch (error) { 22 | log.error('Error getting store', error); 23 | return null; 24 | } 25 | } 26 | 27 | return null; 28 | }; 29 | browser.runtime.onMessage.addListener((request) => { 30 | if (['set-store', 'get-store'].includes(request.action)) { 31 | return storeAccessListener(request); 32 | } 33 | }); 34 | 35 | // For debugging purposes 36 | browser.storage.onChanged.addListener(async () => { 37 | try { 38 | const items = await browser.storage.sync.get(null); 39 | log.debug('DEBUG', items); 40 | } catch (error) { 41 | log.error('Error getting store changes for debugging', error); 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /extension/src/background/throttling.util.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | import { THROTTLING_OPERATION, ACCOUNT_TYPE } from '../global/constants'; 3 | import OperationLimits from '../global/limits/operations'; 4 | 5 | export const isAllowed = (user, operation) => { 6 | if (!user.accountType) return false; 7 | 8 | // Creating a bookmark 9 | if (operation === THROTTLING_OPERATION.CreateBookmark) { 10 | if (!user.bookmarks) return false; 11 | // Check if user exceeds tier limit 12 | if ( 13 | user.bookmarks.length >= 14 | OperationLimits[THROTTLING_OPERATION.CreateBookmark][user.accountType] 15 | ) { 16 | return false; 17 | } 18 | // If within limits, allow user to create bookmark 19 | return true; 20 | } 21 | 22 | // If user is professional or enterprise, they're allowed 23 | // to do anything 24 | if ( 25 | user.accountType === ACCOUNT_TYPE.Professional || 26 | user.accountType === ACCOUNT_TYPE.Enterprise 27 | ) { 28 | return true; 29 | } 30 | 31 | // Default 32 | return false; 33 | }; 34 | -------------------------------------------------------------------------------- /extension/src/components/Buttons/IconButton.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-props-no-spreading */ 2 | /* eslint-disable react/require-default-props */ 3 | /* eslint-disable react/forbid-prop-types */ 4 | 5 | import React, { Suspense, cloneElement } from 'react'; 6 | import { useHistory, useLocation } from 'react-router-dom'; 7 | import styled from 'styled-components'; 8 | import PropTypes from 'prop-types'; 9 | 10 | import { XIcon } from '@primer/octicons-react'; 11 | 12 | const ContainerButton = styled.div` 13 | display: flex; 14 | justify-content: center; 15 | align-items: center; 16 | cursor: pointer; 17 | 18 | /* width: 100%; */ 19 | height: 100%; 20 | `; 21 | 22 | const IconButton = ({ 23 | style = {}, 24 | Icon, 25 | disabled, 26 | to, 27 | onClick = () => {}, 28 | dataTestId, 29 | ...buttonProps 30 | }) => { 31 | const history = useHistory(); 32 | const location = useLocation(); 33 | const navigateToPage = () => { 34 | onClick(); 35 | 36 | if (disabled) return; 37 | if (!to) return; 38 | if (location.pathname === to) return; 39 | history.push(to); 40 | }; 41 | 42 | return ( 43 |54 | Manage pull requests, track file changes, comments, approvals, and 55 | everything code review related from one place. Stay tuned for its 56 | upcoming debut! 57 |
58 |