├── .gitignore ├── .husky └── pre-commit ├── .npmrc ├── .prettierrc.json ├── README.md ├── apps ├── next-app │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── android │ │ ├── .gitignore │ │ ├── .idea │ │ │ ├── .gitignore │ │ │ ├── compiler.xml │ │ │ ├── deploymentTargetDropDown.xml │ │ │ ├── jarRepositories.xml │ │ │ └── misc.xml │ │ ├── app │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── capacitor.build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── androidTest │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── getcapacitor │ │ │ │ │ └── myapp │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── next │ │ │ │ │ │ └── supertokens │ │ │ │ │ │ └── app │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res │ │ │ │ │ ├── drawable-land-hdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-land-mdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-land-xhdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-land-xxhdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-land-xxxhdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-port-hdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-port-mdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-port-xhdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-port-xxhdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-port-xxxhdpi │ │ │ │ │ └── splash.png │ │ │ │ │ ├── drawable-v24 │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ ├── drawable │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ └── splash.png │ │ │ │ │ ├── layout │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── values │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ │ └── xml │ │ │ │ │ └── file_paths.xml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── getcapacitor │ │ │ │ └── myapp │ │ │ │ └── ExampleUnitTest.java │ │ ├── build.gradle │ │ ├── capacitor.settings.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle │ │ └── variables.gradle │ ├── capacitor.config.ts │ ├── config │ │ ├── appInfo.js │ │ └── frontendConfig.ts │ ├── ios │ │ ├── .gitignore │ │ └── App │ │ │ ├── App.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── project.xcworkspace │ │ │ │ └── contents.xcworkspacedata │ │ │ ├── App.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ ├── App │ │ │ ├── App.entitlements │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ ├── AppIcon-512@2x.png │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ └── Splash.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── splash-2732x2732-1.png │ │ │ │ │ ├── splash-2732x2732-2.png │ │ │ │ │ └── splash-2732x2732.png │ │ │ ├── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ └── Info.plist │ │ │ ├── Podfile │ │ │ └── Podfile.lock │ ├── jest.config.js │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── vercel.svg │ ├── src │ │ ├── app │ │ │ ├── auth │ │ │ │ └── callback │ │ │ │ │ ├── apple │ │ │ │ │ └── page.tsx │ │ │ │ │ └── google │ │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── login-result │ │ │ │ └── page.tsx │ │ │ ├── login │ │ │ │ └── page.tsx │ │ │ ├── page.tsx │ │ │ ├── register │ │ │ │ └── page.tsx │ │ │ └── ui │ │ │ │ └── supertokensProvider.tsx │ │ └── lib │ │ │ ├── add.test.ts │ │ │ └── add.ts │ ├── styles │ │ └── globals.css │ ├── tailwind.config.js │ └── tsconfig.json └── next-web │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── config │ ├── appInfo.js │ ├── backendConfig.ts │ └── frontendConfig.ts │ ├── jest.config.js │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── .well-known │ │ └── apple-app-site-association │ ├── favicon.ico │ └── vercel.svg │ ├── src │ ├── app │ │ ├── api │ │ │ └── auth │ │ │ │ └── [[...path]] │ │ │ │ ├── cors.ts │ │ │ │ └── route.ts │ │ ├── auth │ │ │ └── callback │ │ │ │ ├── apple │ │ │ │ └── page.tsx │ │ │ │ └── google │ │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── lib │ │ │ └── sessionUtils.ts │ │ ├── login-result │ │ │ └── page.tsx │ │ ├── login │ │ │ └── page.tsx │ │ ├── page.tsx │ │ ├── register │ │ │ └── page.tsx │ │ └── ui │ │ │ └── supertokensProvider.tsx │ └── pages │ │ └── api │ │ └── auth │ │ └── redirect.ts │ ├── styles │ └── globals.css │ ├── tailwind.config.js │ ├── tsconfig.json │ └── tsconfig.tsbuildinfo ├── jest.config.js ├── package.json ├── packages ├── app │ └── package.json ├── config │ ├── eslint-next.js │ ├── eslint-server.js │ ├── jest-common.js │ ├── jest-next.js │ ├── jest-server.js │ ├── package.json │ ├── tailwind.config.app.js │ ├── tailwind.config.base.js │ └── tailwind.config.web.js ├── lib │ ├── .eslintrc.js │ ├── hooks │ │ ├── useConfirmModalStore.ts │ │ └── useEditingState.ts │ ├── next-apps │ │ └── hooks │ │ │ ├── signout.ts │ │ │ └── useScreenType.ts │ ├── package.json │ ├── tsconfig.json │ └── utils │ │ ├── capacitor.ts │ │ ├── capacitorCookieHandler.ts │ │ ├── common.types.ts │ │ ├── config.ts │ │ ├── cors.ts │ │ ├── handleRegister.ts │ │ ├── logError.ts │ │ ├── navLinks.ts │ │ ├── supertokensNodeUtilities.ts │ │ ├── supertokensUtilities.ts │ │ └── util.ts ├── tsconfig │ ├── README.md │ ├── base.json │ ├── nextjs.json │ ├── package.json │ └── server.json └── ui │ ├── .eslintrc.js │ ├── Button.tsx │ ├── components │ ├── AuthLayout.tsx │ ├── Button.tsx │ ├── ButtonGroup.tsx │ ├── ButtonLink.tsx │ ├── ButtonSpinner.tsx │ ├── ButtonText.tsx │ ├── ConfirmModal │ │ └── ConfirmModal.tsx │ ├── Container.tsx │ ├── Error.tsx │ ├── Form │ │ ├── CustomRadioGroup │ │ │ ├── CustomRadioGroup.tsx │ │ │ └── RadioGroupOptionDouble.tsx │ │ ├── Editable │ │ │ └── SettingsEditableTextForm.tsx │ │ └── SingleFieldTextForm.tsx │ ├── Hero.tsx │ ├── Input.tsx │ ├── InputErrorMsg.tsx │ ├── InputField.tsx │ ├── Label.tsx │ ├── LoadingSpinner.tsx │ ├── LoadingSpinnerPage.tsx │ ├── LoginResult.tsx │ ├── MenuButton.tsx │ ├── MenuLink.tsx │ ├── Modal.tsx │ ├── ProfileDropdown.tsx │ ├── ReturnBreadcrumb.tsx │ ├── SocialButtons.tsx │ ├── Text.tsx │ ├── TextDivider.tsx │ ├── Toast │ │ └── toast.tsx │ ├── TopNav │ │ ├── MobileTopNavWithReturn.tsx │ │ ├── ProfileNavBar.tsx │ │ └── TopNavDesktop.tsx │ └── TryRefreshClientComponent.tsx │ ├── containers │ ├── Auth │ │ └── NoAccountLayout.tsx │ ├── AuthCallback │ │ └── AuthCallback.tsx │ ├── Forms │ │ ├── LoginForm.tsx │ │ └── RegisterForm.tsx │ ├── Layout │ │ └── Layout.tsx │ ├── Login │ │ ├── Login.tsx │ │ └── StackedSocialButtons.tsx │ ├── Overview │ │ └── Overview.tsx │ ├── Register │ │ └── Register.tsx │ └── Settings │ │ └── ProfileInformation.tsx │ ├── icons │ ├── AppleIcon.tsx │ ├── FacebookIcon.tsx │ ├── GithubIcon.tsx │ └── GoogleIcon.tsx │ ├── images │ ├── avatars │ │ ├── avatar-1.png │ │ ├── avatar-2.png │ │ ├── avatar-3.png │ │ ├── avatar-4.png │ │ └── avatar-5.png │ ├── background-auth.jpg │ ├── background-call-to-action.jpg │ ├── background-faqs.jpg │ ├── background-features.jpg │ ├── logos │ │ ├── laravel.svg │ │ ├── mirage.svg │ │ ├── statamic.svg │ │ ├── statickit.svg │ │ ├── transistor.svg │ │ └── tuple.svg │ └── screenshots │ │ ├── contacts.png │ │ ├── expenses.png │ │ ├── inventory.png │ │ ├── payroll.png │ │ ├── profit-loss.png │ │ ├── reporting.png │ │ └── vat-returns.png │ ├── index.tsx │ ├── package.json │ ├── postcss.config.js │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── turbo.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # build 9 | dist 10 | 11 | # testing 12 | coverage 13 | 14 | # next.js 15 | .next/ 16 | out/ 17 | build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | .pnpm-debug.log* 28 | 29 | # local env files 30 | .env.local 31 | .env.development.local 32 | .env.test.local 33 | .env.production.local 34 | 35 | # turbo 36 | .turbo 37 | .env 38 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run test && npx lint-staged 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | node-linker = hoisted 2 | #save-workspace-protocol=false 3 | prefer-workspace-packages=true 4 | auto-install-peers = true 5 | 6 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "semi": false, 4 | "trailingComma": "all", 5 | "printWidth": 80, 6 | "arrowParens": "avoid", 7 | "singleQuote": true 8 | } 9 | -------------------------------------------------------------------------------- /apps/next-app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('config/eslint-next.js'), 3 | parserOptions: { 4 | tsconfigRootDir: __dirname, 5 | project: './tsconfig.json', 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /apps/next-app/.gitignore: -------------------------------------------------------------------------------- 1 | .vercel 2 | -------------------------------------------------------------------------------- /apps/next-app/README.md: -------------------------------------------------------------------------------- 1 | # Next.js + Tailwind CSS Example 2 | 3 | This example shows how to use [Tailwind CSS](https://tailwindcss.com/) [(v3.0)](https://tailwindcss.com/blog/tailwindcss-v3) with Next.js. It follows the steps outlined in the official [Tailwind docs](https://tailwindcss.com/docs/guides/nextjs). 4 | 5 | ## Preview 6 | 7 | Preview the example live on [StackBlitz](http://stackblitz.com/): 8 | 9 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-tailwindcss) 10 | 11 | ## Deploy your own 12 | 13 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): 14 | 15 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss&project-name=with-tailwindcss&repository-name=with-tailwindcss) 16 | 17 | ## How to use 18 | 19 | Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: 20 | 21 | ```bash 22 | npx create-next-app --example with-tailwindcss with-tailwindcss-app 23 | # or 24 | yarn create next-app --example with-tailwindcss with-tailwindcss-app 25 | ``` 26 | 27 | Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). 28 | -------------------------------------------------------------------------------- /apps/next-app/android/.gitignore: -------------------------------------------------------------------------------- 1 | # Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore 2 | 3 | # Built application files 4 | *.apk 5 | *.aar 6 | *.ap_ 7 | *.aab 8 | 9 | # Files for the ART/Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | out/ 19 | # Uncomment the following line in case you need and you don't have the release build type files in your app 20 | # release/ 21 | 22 | # Gradle files 23 | .gradle/ 24 | build/ 25 | 26 | # Local configuration file (sdk path, etc) 27 | local.properties 28 | 29 | # Proguard folder generated by Eclipse 30 | proguard/ 31 | 32 | # Log Files 33 | *.log 34 | 35 | # Android Studio Navigation editor temp files 36 | .navigation/ 37 | 38 | # Android Studio captures folder 39 | captures/ 40 | 41 | # IntelliJ 42 | *.iml 43 | .idea/workspace.xml 44 | .idea/tasks.xml 45 | .idea/gradle.xml 46 | .idea/assetWizardSettings.xml 47 | .idea/dictionaries 48 | .idea/libraries 49 | # Android Studio 3 in .gitignore file. 50 | .idea/caches 51 | .idea/modules.xml 52 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 53 | .idea/navEditor.xml 54 | 55 | # Keystore files 56 | # Uncomment the following lines if you do not want to check your keystore files in. 57 | #*.jks 58 | #*.keystore 59 | 60 | # External native build folder generated in Android Studio 2.2 and later 61 | .externalNativeBuild 62 | .cxx/ 63 | 64 | # Google Services (e.g. APIs or Firebase) 65 | # google-services.json 66 | 67 | # Freeline 68 | freeline.py 69 | freeline/ 70 | freeline_project_description.json 71 | 72 | # fastlane 73 | fastlane/report.xml 74 | fastlane/Preview.html 75 | fastlane/screenshots 76 | fastlane/test_output 77 | fastlane/readme.md 78 | 79 | # Version control 80 | vcs.xml 81 | 82 | # lint 83 | lint/intermediates/ 84 | lint/generated/ 85 | lint/outputs/ 86 | lint/tmp/ 87 | # lint/reports/ 88 | 89 | # Android Profiling 90 | *.hprof 91 | 92 | # Cordova plugins for Capacitor 93 | capacitor-cordova-android-plugins 94 | 95 | # Copied web assets 96 | app/src/main/assets/public 97 | 98 | # Generated Config files 99 | app/src/main/assets/capacitor.config.json 100 | app/src/main/assets/capacitor.plugins.json 101 | app/src/main/res/xml/config.xml 102 | -------------------------------------------------------------------------------- /apps/next-app/android/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /apps/next-app/android/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/next-app/android/.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/next-app/android/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /apps/next-app/android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /apps/next-app/android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /apps/next-app/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | namespace "next.supertokens.app" 5 | compileSdkVersion rootProject.ext.compileSdkVersion 6 | defaultConfig { 7 | applicationId "next.supertokens.app" 8 | minSdkVersion rootProject.ext.minSdkVersion 9 | targetSdkVersion rootProject.ext.targetSdkVersion 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 13 | aaptOptions { 14 | // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. 15 | // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 16 | ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' 17 | } 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | repositories { 28 | flatDir{ 29 | dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' 30 | } 31 | } 32 | 33 | dependencies { 34 | implementation fileTree(include: ['*.jar'], dir: 'libs') 35 | implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" 36 | implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" 37 | implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" 38 | implementation project(':capacitor-android') 39 | testImplementation "junit:junit:$junitVersion" 40 | androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" 41 | androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" 42 | implementation project(':capacitor-cordova-android-plugins') 43 | } 44 | 45 | apply from: 'capacitor.build.gradle' 46 | 47 | try { 48 | def servicesJSON = file('google-services.json') 49 | if (servicesJSON.text) { 50 | apply plugin: 'com.google.gms.google-services' 51 | } 52 | } catch(Exception e) { 53 | logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") 54 | } 55 | -------------------------------------------------------------------------------- /apps/next-app/android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_17 6 | targetCompatibility JavaVersion.VERSION_17 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | implementation project(':capacitor-app') 13 | implementation project(':capacitor-preferences') 14 | implementation project(':capacitor-splash-screen') 15 | 16 | } 17 | 18 | 19 | if (hasProperty('postBuildExtras')) { 20 | postBuildExtras() 21 | } 22 | -------------------------------------------------------------------------------- /apps/next-app/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import android.content.Context; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | import androidx.test.platform.app.InstrumentationRegistry; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * @see Testing documentation 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class ExampleInstrumentedTest { 18 | 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.app", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/java/next/supertokens/app/MainActivity.java: -------------------------------------------------------------------------------- 1 | package next.supertokens.app; 2 | 3 | import com.getcapacitor.BridgeActivity; 4 | 5 | public class MainActivity extends BridgeActivity {} 6 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | next-app-supertokens 4 | next-app-supertokens 5 | next.supertokens.app 6 | next.supertokens.app 7 | 8 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/next-app/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | 14 | @Test 15 | public void addition_isCorrect() throws Exception { 16 | assertEquals(4, 2 + 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/next-app/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:8.0.1' 11 | classpath 'com.google.gms:google-services:4.3.15' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | apply from: "variables.gradle" 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | mavenCentral() 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /apps/next-app/android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../../../node_modules/@capacitor/android/capacitor') 4 | 5 | include ':capacitor-app' 6 | project(':capacitor-app').projectDir = new File('../../../node_modules/@capacitor/app/android') 7 | 8 | include ':capacitor-preferences' 9 | project(':capacitor-preferences').projectDir = new File('../../../node_modules/@capacitor/preferences/android') 10 | 11 | include ':capacitor-splash-screen' 12 | project(':capacitor-splash-screen').projectDir = new File('../../../node_modules/@capacitor/splash-screen/android') 13 | -------------------------------------------------------------------------------- /apps/next-app/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | 24 | -------------------------------------------------------------------------------- /apps/next-app/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /apps/next-app/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /apps/next-app/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /apps/next-app/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /apps/next-app/android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 22 3 | compileSdkVersion = 33 4 | targetSdkVersion = 33 5 | androidxActivityVersion = '1.7.0' 6 | androidxAppCompatVersion = '1.6.1' 7 | androidxCoordinatorLayoutVersion = '1.2.0' 8 | androidxCoreVersion = '1.10.0' 9 | androidxFragmentVersion = '1.5.6' 10 | coreSplashScreenVersion = '1.0.0' 11 | androidxWebkitVersion = '1.6.1' 12 | junitVersion = '4.13.2' 13 | androidxJunitVersion = '1.1.5' 14 | androidxEspressoCoreVersion = '3.5.1' 15 | cordovaAndroidVersion = '10.1.1' 16 | } -------------------------------------------------------------------------------- /apps/next-app/capacitor.config.ts: -------------------------------------------------------------------------------- 1 | import { CapacitorConfig } from '@capacitor/cli' 2 | import { APP_BUNDLE_URL } from 'lib/utils/config' 3 | 4 | const config: CapacitorConfig = { 5 | appId: APP_BUNDLE_URL, 6 | appName: 'next-app-supertokens', 7 | webDir: 'out', 8 | // For live reload: comment out server. 9 | // server: { 10 | // url: 'http://YOUR_IP:3001', 11 | // }, 12 | bundledWebRuntime: false, 13 | plugins: { 14 | SplashScreen: { 15 | launchAutoHide: true, // Set this to false to maintain splash screen on screen and fetch data for example on startup 16 | }, 17 | }, 18 | } 19 | 20 | export default config 21 | -------------------------------------------------------------------------------- /apps/next-app/config/appInfo.js: -------------------------------------------------------------------------------- 1 | import { APP_BUNDLE_URL, FRONTEND_URL } from 'lib/utils/config' 2 | 3 | export const appInfo = { 4 | appName: 'SuperTokens Capacitor Demo App', 5 | apiDomain: FRONTEND_URL, 6 | websiteDomain: APP_BUNDLE_URL, // NOTE: this is the same as the appId in the capacitor.config 7 | apiBasePath: '/api/auth', 8 | websiteBasePath: '/auth', 9 | } 10 | -------------------------------------------------------------------------------- /apps/next-app/config/frontendConfig.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | import { AUTH_MODE } from 'lib/utils/config' 3 | 4 | import { useRouter } from 'next/navigation' 5 | 6 | import ThirdPartyEmailPassword from 'supertokens-auth-react/recipe/thirdpartyemailpassword' 7 | import EmailPassword from 'supertokens-auth-react/recipe/emailpassword' 8 | import Passwordless from 'supertokens-auth-react/recipe/passwordless' 9 | import ThirdParty from 'supertokens-auth-react/recipe/thirdparty' 10 | import ThirdPartyPasswordless from 'supertokens-auth-react/recipe/thirdpartypasswordless' 11 | 12 | import SessionReact from 'supertokens-auth-react/recipe/session' 13 | import { SuperTokensConfig } from 'supertokens-auth-react/lib/build/types' 14 | import { appInfo } from './appInfo' 15 | 16 | type WindowHandlerInterface = Parameters< 17 | NonNullable 18 | >[0] 19 | const routerInfo: { router?: ReturnType; pathName?: string } = 20 | {} 21 | 22 | export function setRouter( 23 | router: ReturnType, 24 | pathName: string, 25 | ) { 26 | routerInfo.router = router 27 | routerInfo.pathName = pathName 28 | } 29 | 30 | const sessionInit = SessionReact.init({ 31 | // cookieDomain: getCookiesDomain(), 32 | onHandleEvent: event => { 33 | if (event.action === 'UNAUTHORISED' || event.action === 'SIGN_OUT') { 34 | window.location.href = '/login' 35 | } 36 | }, 37 | // * 2. Important Capacitor note: 38 | /* 39 | * Note: The 'header' token transfer method is only being used in the app, and not in the web. 40 | * This is a crucial difference in how the application handles sessions compared to the web. 41 | * This design choice has been made due to the specific requirements and limitations in the app environment. 42 | * For more information on the token transfer method, refer to the Supertokens documentation at 43 | * https://supertokens.com/docs/thirdparty/common-customizations/sessions/token-transfer-method 44 | */ 45 | tokenTransferMethod: 'header', 46 | }) 47 | 48 | const configWindowHandler = (original: WindowHandlerInterface) => ({ 49 | ...original, 50 | location: { 51 | ...original.location, 52 | getPathName: () => routerInfo.pathName!, 53 | // @ts-ignore 54 | assign: url => routerInfo.router!.push(url.toString()), 55 | // @ts-ignore 56 | setHref: url => routerInfo.router!.push(url.toString()), 57 | }, 58 | }) 59 | 60 | const thirdPartyEmailPasswordConfig = (): SuperTokensConfig => ({ 61 | appInfo, 62 | recipeList: [ThirdPartyEmailPassword.init(), sessionInit], 63 | windowHandler: configWindowHandler, 64 | }) 65 | 66 | const emailPasswordConfig = (): SuperTokensConfig => ({ 67 | appInfo, 68 | recipeList: [EmailPassword.init(), sessionInit], 69 | windowHandler: configWindowHandler, 70 | }) 71 | 72 | const passwordlessConfig = (): SuperTokensConfig => ({ 73 | appInfo, 74 | recipeList: [ 75 | Passwordless.init({ 76 | contactMethod: 'EMAIL', 77 | }), 78 | sessionInit, 79 | ], 80 | windowHandler: configWindowHandler, 81 | }) 82 | 83 | const thirdPartyConfig = (): SuperTokensConfig => ({ 84 | appInfo, 85 | recipeList: [ThirdParty.init(), sessionInit], 86 | windowHandler: configWindowHandler, 87 | }) 88 | 89 | const thirdPartyPasswordlessConfig = (): SuperTokensConfig => ({ 90 | appInfo, 91 | recipeList: [ 92 | ThirdPartyPasswordless.init({ 93 | contactMethod: 'EMAIL', 94 | }), 95 | sessionInit, 96 | ], 97 | windowHandler: configWindowHandler, 98 | }) 99 | 100 | export function getFrontendConfig(): SuperTokensConfig { 101 | if (AUTH_MODE === 'emailpassword') { 102 | return emailPasswordConfig() 103 | } 104 | 105 | if (AUTH_MODE === 'thirdparty') { 106 | return thirdPartyConfig() 107 | } 108 | 109 | if (AUTH_MODE === 'thirdpartyemailpassword') { 110 | return thirdPartyEmailPasswordConfig() 111 | } 112 | 113 | if (AUTH_MODE === 'passwordless') { 114 | return passwordlessConfig() 115 | } 116 | 117 | return thirdPartyPasswordlessConfig() 118 | } 119 | -------------------------------------------------------------------------------- /apps/next-app/ios/.gitignore: -------------------------------------------------------------------------------- 1 | App/build 2 | App/Pods 3 | App/App/public 4 | DerivedData 5 | xcuserdata 6 | 7 | # Cordova plugins for Capacitor 8 | capacitor-cordova-ios-plugins 9 | 10 | # Generated Config files 11 | App/App/capacitor.config.json 12 | App/App/config.xml 13 | 14 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/App.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.associated-domains 6 | 7 | applinks:nextjs-native.dev 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Capacitor 3 | 4 | @UIApplicationMain 5 | class AppDelegate: UIResponder, UIApplicationDelegate { 6 | 7 | var window: UIWindow? 8 | 9 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 10 | // Override point for customization after application launch. 11 | return true 12 | } 13 | 14 | func applicationWillResignActive(_ application: UIApplication) { 15 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 16 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 17 | } 18 | 19 | func applicationDidEnterBackground(_ application: UIApplication) { 20 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 21 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 22 | } 23 | 24 | func applicationWillEnterForeground(_ application: UIApplication) { 25 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 26 | } 27 | 28 | func applicationDidBecomeActive(_ application: UIApplication) { 29 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 34 | } 35 | 36 | func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { 37 | // Called when the app was launched with a url. Feel free to add additional processing here, 38 | // but if you want the App API to support tracking app url opens, make sure to keep this call 39 | return ApplicationDelegateProxy.shared.application(app, open: url, options: options) 40 | } 41 | 42 | func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { 43 | // Called when the app was launched with an activity, including Universal Links. 44 | // Feel free to add additional processing here, but if you want the App API to support 45 | // tracking app url opens, make sure to keep this call 46 | return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon-512@2x.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash-2732x2732-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash-2732x2732-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash-2732x2732.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | next-app-supertokens 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleURLName 25 | next.supertokens.app 26 | CFBundleURLSchemes 27 | 28 | next-supertokens 29 | next.supertokens.app 30 | 31 | 32 | 33 | CFBundleVersion 34 | $(CURRENT_PROJECT_VERSION) 35 | LSRequiresIPhoneOS 36 | 37 | NSAppTransportSecurity 38 | 39 | NSAllowsLocalNetworking 40 | 41 | 42 | NSUserActivityTypes 43 | 44 | $(PRODUCT_BUNDLE_IDENTIFIER).shortcut 45 | 46 | UILaunchStoryboardName 47 | LaunchScreen 48 | UIMainStoryboardFile 49 | Main 50 | UIRequiredDeviceCapabilities 51 | 52 | armv7 53 | 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationLandscapeLeft 58 | UIInterfaceOrientationLandscapeRight 59 | 60 | UISupportedInterfaceOrientations~ipad 61 | 62 | UIInterfaceOrientationPortrait 63 | UIInterfaceOrientationPortraitUpsideDown 64 | UIInterfaceOrientationLandscapeLeft 65 | UIInterfaceOrientationLandscapeRight 66 | 67 | UIViewControllerBasedStatusBarAppearance 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../../../../node_modules/@capacitor/ios/scripts/pods_helpers' 2 | 3 | platform :ios, '13.0' 4 | use_frameworks! 5 | 6 | # workaround to avoid Xcode caching of Pods that requires 7 | # Product -> Clean Build Folder after new Cordova plugins installed 8 | # Requires CocoaPods 1.6 or newer 9 | install! 'cocoapods', :disable_input_output_paths => true 10 | 11 | def capacitor_pods 12 | pod 'Capacitor', :path => '../../../../node_modules/@capacitor/ios' 13 | pod 'CapacitorCordova', :path => '../../../../node_modules/@capacitor/ios' 14 | pod 'CapacitorApp', :path => '../../../../node_modules/@capacitor/app' 15 | pod 'CapacitorPreferences', :path => '../../../../node_modules/@capacitor/preferences' 16 | pod 'CapacitorSplashScreen', :path => '../../../../node_modules/@capacitor/splash-screen' 17 | end 18 | 19 | target 'App' do 20 | capacitor_pods 21 | # Add your Pods here 22 | end 23 | 24 | post_install do |installer| 25 | assertDeploymentTarget(installer) 26 | end 27 | -------------------------------------------------------------------------------- /apps/next-app/ios/App/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Capacitor (5.5.1): 3 | - CapacitorCordova 4 | - CapacitorApp (5.0.6): 5 | - Capacitor 6 | - CapacitorCordova (5.5.1) 7 | - CapacitorPreferences (5.0.6): 8 | - Capacitor 9 | - CapacitorSplashScreen (5.0.6): 10 | - Capacitor 11 | 12 | DEPENDENCIES: 13 | - "Capacitor (from `../../../../node_modules/@capacitor/ios`)" 14 | - "CapacitorApp (from `../../../../node_modules/@capacitor/app`)" 15 | - "CapacitorCordova (from `../../../../node_modules/@capacitor/ios`)" 16 | - "CapacitorPreferences (from `../../../../node_modules/@capacitor/preferences`)" 17 | - "CapacitorSplashScreen (from `../../../../node_modules/@capacitor/splash-screen`)" 18 | 19 | EXTERNAL SOURCES: 20 | Capacitor: 21 | :path: "../../../../node_modules/@capacitor/ios" 22 | CapacitorApp: 23 | :path: "../../../../node_modules/@capacitor/app" 24 | CapacitorCordova: 25 | :path: "../../../../node_modules/@capacitor/ios" 26 | CapacitorPreferences: 27 | :path: "../../../../node_modules/@capacitor/preferences" 28 | CapacitorSplashScreen: 29 | :path: "../../../../node_modules/@capacitor/splash-screen" 30 | 31 | SPEC CHECKSUMS: 32 | Capacitor: 9da0a2415e3b6098511f8b5ffdb578d91ee79f8f 33 | CapacitorApp: 024e1b1bea5f883d79f6330d309bc441c88ad04a 34 | CapacitorCordova: e128cc7688c070ca0bfa439898a5f609da8dbcfe 35 | CapacitorPreferences: f03954bcb0ff09c792909e46bff88e3183c16b10 36 | CapacitorSplashScreen: 5fa2ab5e46cf5cc530cf16a51c80c7a986579ccd 37 | 38 | PODFILE CHECKSUM: 58bf0f04a49daf38d739a074ec80e5d1f262a3fd 39 | 40 | COCOAPODS: 1.14.3 41 | -------------------------------------------------------------------------------- /apps/next-app/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../jest.config') 2 | 3 | module.exports = { 4 | ...base, 5 | name: 'next-app', 6 | displayName: 'Next-app Tests', 7 | } 8 | -------------------------------------------------------------------------------- /apps/next-app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /apps/next-app/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | 3 | module.exports = { 4 | output: 'export', 5 | reactStrictMode: true, 6 | transpilePackages: ['ui, lib'], 7 | } 8 | -------------------------------------------------------------------------------- /apps/next-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-app", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --hostname 0.0.0.0", 7 | "build": "next build && npx cap sync ios && npx cap sync android", 8 | "start": "next start", 9 | "open:ios": "npx cap sync ios && npx cap open ios", 10 | "open:android": "npx cap sync android && npx cap open android", 11 | "sync:app": "npx cap sync", 12 | "export": "next export", 13 | "ionic:build": "npm run build", 14 | "ionic:serve": "npm run start" 15 | }, 16 | "dependencies": { 17 | "@capacitor/android": "^5.5.1", 18 | "@capacitor/app": "^5.0.6", 19 | "@capacitor/cli": "^5.5.1", 20 | "@capacitor/core": "^5.5.1", 21 | "@capacitor/ios": "^5.5.1", 22 | "@capacitor/preferences": "^5.0.6", 23 | "@capacitor/splash-screen": "^5.0.6", 24 | "app": "workspace:*", 25 | "autoprefixer": "10.4.15" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/next-app/postcss.config.js: -------------------------------------------------------------------------------- 1 | // If you want to use other PostCSS plugins, see the following: 2 | // https://tailwindcss.com/docs/using-with-preprocessors 3 | module.exports = { 4 | plugins: { 5 | tailwindcss: {}, 6 | autoprefixer: {}, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /apps/next-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/public/favicon.ico -------------------------------------------------------------------------------- /apps/next-app/public/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-app/public/index.html -------------------------------------------------------------------------------- /apps/next-app/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /apps/next-app/src/app/auth/callback/apple/page.tsx: -------------------------------------------------------------------------------- 1 | import { AuthCallback } from 'ui/containers/AuthCallback/AuthCallback' 2 | import React from 'react' 3 | 4 | const AppleCallback = () => 5 | 6 | export default AppleCallback 7 | -------------------------------------------------------------------------------- /apps/next-app/src/app/auth/callback/google/page.tsx: -------------------------------------------------------------------------------- 1 | import { AuthCallback } from 'ui/containers/AuthCallback/AuthCallback' 2 | import React from 'react' 3 | 4 | const GoogleCallback = () => 5 | 6 | export default GoogleCallback 7 | -------------------------------------------------------------------------------- /apps/next-app/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from 'lib/utils/util' 2 | import { Work_Sans } from 'next/font/google' 3 | import '../../styles/globals.css' 4 | import { Metadata } from 'next' 5 | import { SuperTokensProvider } from './ui/supertokensProvider' 6 | 7 | const fontSans = Work_Sans({ 8 | subsets: ['latin'], 9 | variable: '--font-work-sans', 10 | weight: '400', 11 | }) 12 | 13 | export async function generateMetadata() { 14 | const metadata: Metadata = { 15 | title: { 16 | default: `Welcome to Next.js Native | Next.js Native`, 17 | template: `%s | Next.js Native`, 18 | }, 19 | } 20 | 21 | return metadata 22 | } 23 | 24 | export default async function RootLayout({ 25 | // Layouts must accept a children prop. 26 | // This will be populated with nested layouts or pages 27 | children, 28 | }: { 29 | children: React.ReactNode 30 | }) { 31 | return ( 32 | 33 | 34 | 35 |
{children}
36 | 37 |
38 | 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /apps/next-app/src/app/login-result/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { LoginResult } from 'ui/components/LoginResult' 3 | 4 | const LoginResultPage = () => 5 | 6 | export default LoginResultPage 7 | -------------------------------------------------------------------------------- /apps/next-app/src/app/login/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { LoginComponent } from 'ui/containers/Login/Login' 3 | 4 | const LoginPage = () => 5 | 6 | export default LoginPage 7 | -------------------------------------------------------------------------------- /apps/next-app/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Hero } from 'ui/components/Hero' 4 | import React, { useEffect } from 'react' 5 | 6 | import '../../styles/globals.css' 7 | import { APP_BUNDLE_URL, PROD_URL_NO_HTTPS } from 'lib/utils/config' 8 | import { useRouter } from 'next/navigation' 9 | import { Capacitor } from '@capacitor/core' 10 | import { App as CapApp } from '@capacitor/app' 11 | 12 | const HomePage = () => { 13 | const router = useRouter() 14 | 15 | useEffect(() => { 16 | // add capacitor listeners 17 | if (Capacitor.isNativePlatform()) { 18 | // init services 19 | CapApp.addListener('backButton', () => { 20 | router.back() 21 | }) 22 | 23 | CapApp.addListener('appUrlOpen', (data: any) => { 24 | const isOpenedFromOpenAppUrl = data.url.includes(`${APP_BUNDLE_URL}`) 25 | 26 | const isOpenedFromWeb = data.url === PROD_URL_NO_HTTPS 27 | 28 | if (isOpenedFromOpenAppUrl) { 29 | const slug = data.url.split(':/').pop() 30 | 31 | router.push(slug) 32 | } 33 | 34 | if (isOpenedFromWeb) { 35 | const slug = data.url.split(`${PROD_URL_NO_HTTPS}`).pop() 36 | router.push(slug) 37 | } 38 | }) 39 | } 40 | }, []) 41 | 42 | return ( 43 |
44 | 45 |
46 | ) 47 | } 48 | 49 | export default HomePage 50 | -------------------------------------------------------------------------------- /apps/next-app/src/app/register/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { RegisterComponent } from 'ui/containers/Register/Register' 3 | 4 | const RegisterPage = () => 5 | 6 | export default RegisterPage 7 | -------------------------------------------------------------------------------- /apps/next-app/src/app/ui/supertokensProvider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import React from 'react' 4 | import SuperTokensReact, { SuperTokensWrapper } from 'supertokens-auth-react' 5 | import { usePathname, useRouter } from 'next/navigation' 6 | import capacitorCookieHandler from 'lib/utils/capacitorCookieHandler' 7 | import { getFrontendConfig, setRouter } from '../../../config/frontendConfig' 8 | 9 | if (typeof window !== 'undefined') { 10 | // we only want to call this init function on the frontend, so we check typeof window !== 'undefined' 11 | SuperTokensReact.init({ 12 | ...getFrontendConfig(), 13 | 14 | /* 15 | * 1. Important Capacitor note: 16 | * This section deals with a challenge faced while working with SDKs in the context of frameworks like Electron/Tauri and Capacitor. 17 | * These frameworks add an abstraction layer on top of the browser logic, which causes issues with how the SDK uses frontend cookies for information storage. 18 | * Because of this, a cookie handler is necessary, regardless of the token transfer method specified in the frontendConfig. 19 | * 20 | * In this instance, we are using the 'capacitorCookieHandler' to handle cookies. 21 | */ 22 | cookieHandler: capacitorCookieHandler, 23 | enableDebugLogs: true, 24 | }) 25 | } 26 | 27 | export const SuperTokensProvider: React.FC> = ({ 28 | children, 29 | }) => { 30 | setRouter(useRouter(), usePathname() || window.location.pathname) 31 | 32 | return {children} 33 | } 34 | -------------------------------------------------------------------------------- /apps/next-app/src/lib/add.test.ts: -------------------------------------------------------------------------------- 1 | import add from '@src/lib/add' 2 | 3 | describe('testing add', () => { 4 | it('should be 3', () => { 5 | expect(add(1, 2)).toBe(3) 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /apps/next-app/src/lib/add.ts: -------------------------------------------------------------------------------- 1 | const add = (a: number, b: number): number => a + b 2 | 3 | export default add 4 | -------------------------------------------------------------------------------- /apps/next-app/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /apps/next-app/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const appBaseConfig = require('../../packages/config/tailwind.config.app.js') 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | presets: [appBaseConfig], 6 | 7 | content: [ 8 | './src/pages/**/*.{js,ts,jsx,tsx}', 9 | '../../packages/ui/**/*.{js,ts,jsx,tsx}', 10 | // in case of using app router too: 11 | // './src/app/**/*.{js,ts,jsx,tsx}', 12 | ], 13 | } 14 | -------------------------------------------------------------------------------- /apps/next-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@src/*": [ 7 | "src/*" 8 | ] 9 | }, 10 | "jsx": "preserve", 11 | "plugins": [ 12 | { 13 | "name": "next" 14 | } 15 | ], 16 | "strictNullChecks": true 17 | }, 18 | "include": [ 19 | "next-env.d.ts", 20 | "**/*.ts", 21 | "**/*.tsx", 22 | ".next/types/**/*.ts" 23 | ], 24 | "exclude": [ 25 | "node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /apps/next-web/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('config/eslint-next.js'), 3 | parserOptions: { 4 | tsconfigRootDir: __dirname, 5 | project: './tsconfig.json', 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /apps/next-web/.gitignore: -------------------------------------------------------------------------------- 1 | .vercel 2 | -------------------------------------------------------------------------------- /apps/next-web/README.md: -------------------------------------------------------------------------------- 1 | # Next.js + Tailwind CSS Example 2 | 3 | This example shows how to use [Tailwind CSS](https://tailwindcss.com/) [(v3.0)](https://tailwindcss.com/blog/tailwindcss-v3) with Next.js. It follows the steps outlined in the official [Tailwind docs](https://tailwindcss.com/docs/guides/nextjs). 4 | 5 | ## Preview 6 | 7 | Preview the example live on [StackBlitz](http://stackblitz.com/): 8 | 9 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-tailwindcss) 10 | 11 | ## Deploy your own 12 | 13 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): 14 | 15 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss&project-name=with-tailwindcss&repository-name=with-tailwindcss) 16 | 17 | ## How to use 18 | 19 | Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example: 20 | 21 | ```bash 22 | npx create-next-app --example with-tailwindcss with-tailwindcss-app 23 | # or 24 | yarn create next-app --example with-tailwindcss with-tailwindcss-app 25 | ``` 26 | 27 | Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). 28 | -------------------------------------------------------------------------------- /apps/next-web/config/appInfo.js: -------------------------------------------------------------------------------- 1 | import { FRONTEND_URL } from 'lib/utils/config' 2 | 3 | export const appInfo = { 4 | appName: 'SuperTokens Capacitor Demo Web', 5 | apiDomain: FRONTEND_URL, 6 | websiteDomain: FRONTEND_URL, 7 | apiBasePath: '/api/auth', 8 | websiteBasePath: '/auth', 9 | } 10 | -------------------------------------------------------------------------------- /apps/next-web/config/frontendConfig.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | import { AUTH_MODE } from 'lib/utils/config' 3 | 4 | import { useRouter } from 'next/navigation' 5 | 6 | import ThirdPartyEmailPasswordReact from 'supertokens-auth-react/recipe/thirdpartyemailpassword' 7 | import EmailPassword from 'supertokens-auth-react/recipe/emailpassword' 8 | import Passwordless from 'supertokens-auth-react/recipe/passwordless' 9 | import ThirdParty from 'supertokens-auth-react/recipe/thirdparty' 10 | import ThirdPartyPasswordless from 'supertokens-auth-react/recipe/thirdpartypasswordless' 11 | 12 | import SessionReact from 'supertokens-auth-react/recipe/session' 13 | import { SuperTokensConfig } from 'supertokens-auth-react/lib/build/types' 14 | import { appInfo } from './appInfo' 15 | 16 | type WindowHandlerInterface = Parameters< 17 | NonNullable 18 | >[0] 19 | const routerInfo: { router?: ReturnType; pathName?: string } = 20 | {} 21 | 22 | export function setRouter( 23 | router: ReturnType, 24 | pathName: string, 25 | ) { 26 | routerInfo.router = router 27 | routerInfo.pathName = pathName 28 | } 29 | 30 | const sessionInit = SessionReact.init({ 31 | // cookieDomain: getCookiesDomain(), 32 | 33 | onHandleEvent: event => { 34 | if (event.action === 'UNAUTHORISED' || event.action === 'SIGN_OUT') { 35 | window.location.href = '/login' 36 | } 37 | }, 38 | // * 3. Important Capacitor note: 39 | // * Here we are not setting the tokenTransferMethod to 'header' as it's only used for the app not the web. 40 | }) 41 | 42 | const configWindowHandler = (original: WindowHandlerInterface) => ({ 43 | ...original, 44 | location: { 45 | ...original.location, 46 | getPathName: () => routerInfo.pathName!, 47 | // @ts-ignore 48 | assign: url => routerInfo.router!.push(url.toString()), 49 | // @ts-ignore 50 | setHref: url => routerInfo.router!.push(url.toString()), 51 | }, 52 | }) 53 | 54 | const thirdPartyEmailPasswordConfig = (): SuperTokensConfig => ({ 55 | appInfo, 56 | recipeList: [ThirdPartyEmailPasswordReact.init(), sessionInit], 57 | windowHandler: configWindowHandler, 58 | }) 59 | 60 | const emailPasswordConfig = (): SuperTokensConfig => ({ 61 | appInfo, 62 | recipeList: [EmailPassword.init(), sessionInit], 63 | windowHandler: configWindowHandler, 64 | }) 65 | 66 | const passwordlessConfig = (): SuperTokensConfig => ({ 67 | appInfo, 68 | recipeList: [ 69 | Passwordless.init({ 70 | contactMethod: 'EMAIL', 71 | }), 72 | sessionInit, 73 | ], 74 | windowHandler: configWindowHandler, 75 | }) 76 | 77 | const thirdPartyConfig = (): SuperTokensConfig => ({ 78 | appInfo, 79 | recipeList: [ThirdParty.init(), sessionInit], 80 | windowHandler: configWindowHandler, 81 | }) 82 | 83 | const thirdPartyPasswordlessConfig = (): SuperTokensConfig => ({ 84 | appInfo, 85 | recipeList: [ 86 | ThirdPartyPasswordless.init({ 87 | contactMethod: 'EMAIL', 88 | }), 89 | sessionInit, 90 | ], 91 | windowHandler: configWindowHandler, 92 | }) 93 | 94 | export function getFrontendConfig(): SuperTokensConfig { 95 | if (AUTH_MODE === 'emailpassword') { 96 | return emailPasswordConfig() 97 | } 98 | 99 | if (AUTH_MODE === 'thirdparty') { 100 | return thirdPartyConfig() 101 | } 102 | 103 | if (AUTH_MODE === 'thirdpartyemailpassword') { 104 | return thirdPartyEmailPasswordConfig() 105 | } 106 | 107 | if (AUTH_MODE === 'passwordless') { 108 | return passwordlessConfig() 109 | } 110 | 111 | return thirdPartyPasswordlessConfig() 112 | } 113 | -------------------------------------------------------------------------------- /apps/next-web/jest.config.js: -------------------------------------------------------------------------------- 1 | const base = require('../../jest.config') 2 | 3 | module.exports = { 4 | ...base, 5 | name: 'next-app', 6 | displayName: 'Next-app Tests', 7 | } 8 | -------------------------------------------------------------------------------- /apps/next-web/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | // NOTE: This file should not be edited 6 | // see https://nextjs.org/docs/basic-features/typescript for more information. 7 | -------------------------------------------------------------------------------- /apps/next-web/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | 5 | transpilePackages: ['ui, lib'], 6 | } 7 | 8 | module.exports = nextConfig 9 | -------------------------------------------------------------------------------- /apps/next-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-web", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --port 3001", 7 | "build": "next build", 8 | "start": "next start --port 3001", 9 | "lint": "eslint src --fix", 10 | "analyze": "cross-env ANALYZE=true next build" 11 | }, 12 | "dependencies": { 13 | "@types/express": "^4.17.15", 14 | "app": "workspace:*", 15 | "autoprefixer": "10.4.15", 16 | "supertokens-node": "^16.3.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/next-web/postcss.config.js: -------------------------------------------------------------------------------- 1 | // If you want to use other PostCSS plugins, see the following: 2 | // https://tailwindcss.com/docs/using-with-preprocessors 3 | module.exports = { 4 | plugins: { 5 | tailwindcss: {}, 6 | autoprefixer: {}, 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /apps/next-web/public/.well-known/apple-app-site-association: -------------------------------------------------------------------------------- 1 | { 2 | "applinks": { 3 | "apps": [], 4 | "details": [ 5 | { 6 | "appID": "F23PQPA6YX.next.supertokens.app", 7 | "paths": [ 8 | "NOT /api/*", 9 | "*" 10 | ] 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/next-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobSchilderr/nextjs-native-starter/a30f2c24d8bdf97d09510b9865e89e3cdc3bb28f/apps/next-web/public/favicon.ico -------------------------------------------------------------------------------- /apps/next-web/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /apps/next-web/src/app/api/auth/[[...path]]/route.ts: -------------------------------------------------------------------------------- 1 | import SuperTokens from 'supertokens-node' 2 | import { getAppDirRequestHandler } from 'supertokens-node/nextjs' 3 | import { NextRequest, NextResponse } from 'next/server' 4 | import { ALLOWED_CORS_URLS } from 'lib/utils/config' 5 | import { ensureSuperTokensInit } from '../../../../../config/backendConfig' 6 | import cors, { CorsOptions } from './cors'; 7 | 8 | ensureSuperTokensInit(); 9 | 10 | const corsOptions: CorsOptions = { 11 | origin: ALLOWED_CORS_URLS, 12 | credentials: true, 13 | allowedHeaders: ["content-type", ...SuperTokens.getAllCORSHeaders()], 14 | }; 15 | const handleCall = getAppDirRequestHandler(NextResponse); 16 | async function handleCallWithCORS(request: NextRequest) { 17 | const res = await handleCall(request); 18 | return cors(request, res, corsOptions); 19 | } 20 | 21 | export async function OPTIONS(request: NextRequest) { 22 | return cors(request, new NextResponse(null, { status: 204 }), corsOptions); 23 | } 24 | 25 | export async function GET(request: NextRequest) { 26 | const res = await handleCallWithCORS(request) 27 | if (!res.headers.has('Cache-Control')) { 28 | // This is needed for production deployments with Vercel 29 | res.headers.set( 30 | 'Cache-Control', 31 | 'no-cache, no-store, max-age=0, must-revalidate', 32 | ) 33 | } 34 | return res 35 | } 36 | 37 | export async function POST(request: NextRequest) { 38 | return handleCallWithCORS(request) 39 | } 40 | 41 | export async function DELETE(request: NextRequest) { 42 | return handleCallWithCORS(request) 43 | } 44 | 45 | export async function PUT(request: NextRequest) { 46 | return handleCallWithCORS(request) 47 | } 48 | 49 | export async function PATCH(request: NextRequest) { 50 | return handleCallWithCORS(request) 51 | } 52 | 53 | export async function HEAD(request: NextRequest) { 54 | return handleCallWithCORS(request) 55 | } 56 | -------------------------------------------------------------------------------- /apps/next-web/src/app/auth/callback/apple/page.tsx: -------------------------------------------------------------------------------- 1 | import { AuthCallback } from 'ui/containers/AuthCallback/AuthCallback' 2 | import React from 'react' 3 | 4 | const AppleCallback = () => 5 | 6 | export default AppleCallback 7 | -------------------------------------------------------------------------------- /apps/next-web/src/app/auth/callback/google/page.tsx: -------------------------------------------------------------------------------- 1 | import { AuthCallback } from 'ui/containers/AuthCallback/AuthCallback' 2 | import React from 'react' 3 | 4 | const GoogleCallback = () => 5 | 6 | export default GoogleCallback 7 | -------------------------------------------------------------------------------- /apps/next-web/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from 'lib/utils/util' 2 | import { Work_Sans } from 'next/font/google' 3 | import '../../styles/globals.css' 4 | import { Metadata } from 'next' 5 | import { SuperTokensProvider } from './ui/supertokensProvider' 6 | 7 | const fontSans = Work_Sans({ 8 | subsets: ['latin'], 9 | variable: '--font-work-sans', 10 | weight: '400', 11 | }) 12 | 13 | export async function generateMetadata() { 14 | const metadata: Metadata = { 15 | title: { 16 | default: `Welcome to Next.js Native | Next.js Native`, 17 | template: `%s | Next.js Native`, 18 | }, 19 | } 20 | 21 | return metadata 22 | } 23 | 24 | export default async function RootLayout({ 25 | // Layouts must accept a children prop. 26 | // This will be populated with nested layouts or pages 27 | children, 28 | }: { 29 | children: React.ReactNode 30 | }) { 31 | return ( 32 | 33 | 34 | 35 |
{children}
36 | 37 |
38 | 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /apps/next-web/src/app/login-result/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { LoginResult } from 'ui/components/LoginResult' 3 | 4 | const LoginResultPage = () => 5 | 6 | export default LoginResultPage 7 | -------------------------------------------------------------------------------- /apps/next-web/src/app/login/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { LoginComponent } from 'ui/containers/Login/Login' 3 | 4 | const LoginPage = () => 5 | 6 | export default LoginPage 7 | -------------------------------------------------------------------------------- /apps/next-web/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Hero } from 'ui/components/Hero' 3 | 4 | const HomePage = () => ( 5 |
6 | 7 |
8 | ) 9 | 10 | export default HomePage 11 | -------------------------------------------------------------------------------- /apps/next-web/src/app/register/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { RegisterComponent } from 'ui/containers/Register/Register' 3 | 4 | const RegisterPage = () => 5 | 6 | export default RegisterPage 7 | -------------------------------------------------------------------------------- /apps/next-web/src/app/ui/supertokensProvider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import React from 'react' 4 | import SuperTokensReact, { SuperTokensWrapper } from 'supertokens-auth-react' 5 | import { usePathname, useRouter } from 'next/navigation' 6 | import { getFrontendConfig, setRouter } from '../../../config/frontendConfig' 7 | 8 | if (typeof window !== 'undefined') { 9 | // we only want to call this init function on the frontend, so we check typeof window !== 'undefined' 10 | SuperTokensReact.init(getFrontendConfig()) 11 | } 12 | 13 | export const SuperTokensProvider: React.FC> = ({ 14 | children, 15 | }) => { 16 | setRouter(useRouter(), usePathname() || window.location.pathname) 17 | 18 | return {children} 19 | } 20 | -------------------------------------------------------------------------------- /apps/next-web/src/pages/api/auth/redirect.ts: -------------------------------------------------------------------------------- 1 | // todo: refactor this page to app router 2 | 3 | /** 4 | * @description redirect auth page to app page 5 | */ 6 | import { NextApiRequest, NextApiResponse } from 'next' 7 | import NextCors from 'nextjs-cors' 8 | import { APP_BUNDLE_URL } from 'lib/utils/config' 9 | 10 | export default async function redirectAuthUrl( 11 | req: NextApiRequest & Request, 12 | res: NextApiResponse & Response, 13 | ) { 14 | // NOTE: We need CORS only if we are querying the APIs from a different origin 15 | await NextCors(req, res, { 16 | methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'], 17 | origin: '*', 18 | }) 19 | 20 | if (req.query?.token) { 21 | const redirectUrl = `${APP_BUNDLE_URL}://auth/reset-password?token=${req.query.token}&rid=thirdpartyemailpassword` 22 | return res.redirect(redirectUrl) 23 | } 24 | 25 | const code = req.query?.code ?? null 26 | if (req.query?.provider && code) { 27 | let queryClone = { ...req.query } 28 | // Remove the provider query since we use that for the path 29 | delete queryClone.provider 30 | 31 | // Create a query string that consumes all current query params from the url 32 | let queryParts: string[] = [] 33 | Object.keys(queryClone).forEach(key => { 34 | // We need to URL encode the value of the query to make it URL friendly 35 | queryParts.push(`${key}=${encodeURIComponent(queryClone[key] as string)}`) 36 | }) 37 | 38 | // Combine all current query params in a single string 39 | let queryString = queryParts.length === 0 ? '' : queryParts.join('&') 40 | 41 | // if you get an issue with 'invalid state' maybe change the '&' back to '?'. At least this works locally: 42 | const redirectUrl = `${APP_BUNDLE_URL}://auth/callback/${req.query.provider}&${queryString}` 43 | return res.redirect(redirectUrl) 44 | } 45 | 46 | return res.redirect(`${APP_BUNDLE_URL}://`) 47 | } 48 | -------------------------------------------------------------------------------- /apps/next-web/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /apps/next-web/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const webBaseConfig = require('../../packages/config/tailwind.config.web.js') 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | presets: [webBaseConfig], 6 | 7 | content: [ 8 | './src/pages/**/*.{js,ts,jsx,tsx}', 9 | '../../packages/ui/**/*.{js,ts,jsx,tsx}', 10 | // in case of using app router too: 11 | // './src/app/**/*.{js,ts,jsx,tsx}', 12 | ], 13 | } 14 | -------------------------------------------------------------------------------- /apps/next-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@src/*": ["src/*"] 7 | }, 8 | "jsx": "preserve", 9 | "plugins": [ 10 | { 11 | "name": "next" 12 | } 13 | ], 14 | "strictNullChecks": true 15 | }, 16 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 17 | "exclude": ["node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | const fromRoot = d => path.join(__dirname, d) 4 | 5 | module.exports = { 6 | roots: [fromRoot('apps/next-app')], 7 | resetMocks: true, 8 | coveragePathIgnorePatterns: [], 9 | collectCoverageFrom: ['/src/**/*.{js,ts,tsx}'], 10 | coverageThreshold: null, 11 | testEnvironment: 'jsdom', 12 | transform: { 13 | '^.+\\.tsx?$': 'esbuild-jest', 14 | '^.+\\.jsx?$': 'esbuild-jest', 15 | }, 16 | setupFilesAfterEnv: ['@testing-library/jest-dom'], 17 | moduleDirectories: ['node_modules'], 18 | moduleFileExtensions: ['js', 'jsx', 'json', 'ts', 'tsx'], 19 | moduleNameMapper: { 20 | '@src/(.*)': fromRoot('apps/next-app/src/$1'), 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "turborepo-basic-yarn", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "turbo run build", 7 | "dev": "turbo run dev --parallel", 8 | "test": "turbo run test", 9 | "lint": "turbo run lint", 10 | "format": "prettier --write \"**/*.{ts,tsx,md}\"", 11 | "prepare": "husky install" 12 | }, 13 | "dependencies": { 14 | "app": "workspace:*", 15 | "config": "workspace:*", 16 | "lib": "workspace:*", 17 | "tsconfig": "workspace:*", 18 | "ui": "workspace:*" 19 | }, 20 | "devDependencies": { 21 | "@testing-library/jest-dom": "^5.16.5", 22 | "@testing-library/react": "^14.0.0", 23 | "@testing-library/react-hooks": "^8.0.1", 24 | "@testing-library/user-event": "^14.4.3", 25 | "@types/jest": "^29.5.1", 26 | "esbuild": "^0.17.18", 27 | "esbuild-jest": "^0.5.0", 28 | "husky": "^8.0.3", 29 | "identity-obj-proxy": "^3.0.0", 30 | "jest": "^29.5.0", 31 | "lint-staged": "^13.2.2", 32 | "msw": "^1.2.1", 33 | "prettier": "3.0.3", 34 | "ts-node": "^10.9.1", 35 | "turbo": "^1.10.16", 36 | "typescript": "5.2.2" 37 | }, 38 | "resolutions": { 39 | "typescript": "5.2.2", 40 | "eslint": "8.5.0", 41 | "@types/react": "18.2.21", 42 | "@types/react-dom": "18.2.14" 43 | }, 44 | "lint-staged": { 45 | "apps/**/*.{js,ts,jsx,tsx}": [ 46 | "eslint --fix" 47 | ], 48 | "packages/ui/**/*.{js,ts,jsx,tsx}": [ 49 | "eslint --fix" 50 | ], 51 | "*.json": [ 52 | "prettier --write" 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "Shared dependencies for all apps", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@headlessui/react": "^1.7.17", 14 | "@heroicons/react": "^2.0.18", 15 | "@hookform/resolvers": "^3.3.1", 16 | "@tailwindcss/aspect-ratio": "^0.4.2", 17 | "@tailwindcss/forms": "^0.5.6", 18 | "@tailwindcss/typography": "^0.5.10", 19 | "@tippyjs/react": "^4.2.6", 20 | "autoprefixer": "10.4.15", 21 | "clsx": "^2.0.0", 22 | "next": "^14.0.0", 23 | "nextjs-cors": "^2.1.2", 24 | "react": "^18.2.0", 25 | "react-dom": "^18.2.0", 26 | "react-hook-form": "^7.46.1", 27 | "react-hot-toast": "^2.4.1", 28 | "react-responsive": "^9.0.2", 29 | "supertokens-auth-react": "^0.35.6", 30 | "supertokens-web-js": "^0.8.0", 31 | "tailwind-merge": "^1.14.0", 32 | "tailwindcss": "^3.3.3", 33 | "zod": "^3.22.2", 34 | "zustand": "4.4.1" 35 | }, 36 | "devDependencies": { 37 | "@types/react": "18.2.21", 38 | "@types/react-dom": "18.2.14", 39 | "eslint": "^8.5.0", 40 | "msw": "^1.2.1", 41 | "postcss": "8.4.31", 42 | "prettier": "3.0.3", 43 | "typescript": "5.2.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/config/eslint-next.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | node: true, 5 | }, 6 | extends: [ 7 | 'next', 8 | 'airbnb', 9 | 'airbnb-typescript', 10 | 'plugin:import/recommended', 11 | 'plugin:import/typescript', 12 | 'prettier', 13 | 'turbo', 14 | ], 15 | plugins: ['@typescript-eslint', 'import'], 16 | settings: { 17 | next: { 18 | rootDir: ['apps/*/', 'packages/*/'], 19 | }, 20 | 'import/parsers': { 21 | '@typescript-eslint/parser': ['.ts', '.tsx'], 22 | }, 23 | 'import/resolver': { 24 | typescript: { 25 | alwaysTryTypes: true, 26 | project: ['apps/*/tsconfig.json'], 27 | }, 28 | }, 29 | }, 30 | rules: { 31 | 'turbo/no-undeclared-env-vars': 'error', 32 | 'prefer-const': 'off', 33 | 'import/no-extraneous-dependencies': 'off', 34 | // react 35 | 'react/require-default-props': 'off', 36 | 'react/react-in-jsx-scope': 'off', 37 | 'import/prefer-default-export': 'off', 38 | 'react/jsx-props-no-spreading': 'off', 39 | 40 | 'react/function-component-definition': [ 41 | 2, 42 | { 43 | namedComponents: 'arrow-function', 44 | }, 45 | ], 46 | 47 | // next 48 | '@next/next/no-img-element': 'off', // on iOS and Android we can't use next/image 49 | '@next/next/no-html-link-for-pages': 'off', 50 | }, 51 | overrides: [ 52 | { 53 | // 3) Now we enable eslint-plugin-testing-library rules or preset only for matching files! 54 | env: { 55 | jest: true, 56 | }, 57 | files: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'], 58 | extends: ['plugin:testing-library/react', 'plugin:jest/recommended'], 59 | rules: { 60 | 'turbo/no-undeclared-env-vars': 'error', 61 | 62 | 'import/no-extraneous-dependencies': [ 63 | 'off', 64 | { devDependencies: ['**/?(*.)+(spec|test).[jt]s?(x)'] }, 65 | ], 66 | }, 67 | }, 68 | ], 69 | ignorePatterns: [ 70 | '**/*.js', 71 | '**/*.json', 72 | 'node_modules', 73 | 'public', 74 | 'styles', 75 | '.next', 76 | 'coverage', 77 | 'dist', 78 | '.turbo', 79 | ], 80 | } 81 | -------------------------------------------------------------------------------- /packages/config/eslint-server.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | }, 5 | extends: [ 6 | 'eslint:recommended', 7 | 'plugin:@typescript-eslint/recommended', 8 | 'airbnb-base', 9 | 'airbnb-typescript/base', 10 | 'plugin:import/errors', 11 | 'plugin:import/warnings', 12 | 'plugin:import/typescript', 13 | 'prettier', 14 | ], 15 | plugins: ['import', '@typescript-eslint'], 16 | parserOptions: { 17 | project: ['./tsconfig.json'], 18 | }, 19 | settings: { 20 | 'import/parsers': { 21 | '@typescript-eslint/parser': ['.ts'], 22 | }, 23 | 'import/resolver': { 24 | node: { 25 | extensions: ['.js', '.ts'], 26 | moduleDirectory: ['node_modules', 'src/'], 27 | }, 28 | typescript: { 29 | alwaysTryTypes: true, 30 | project: '.', 31 | }, 32 | }, 33 | }, 34 | overrides: [ 35 | { 36 | env: { 37 | jest: true, 38 | }, 39 | files: ['**/__tests__/**/*.[jt]s', '**/?(*.)+(spec|test).[jt]s'], 40 | extends: ['plugin:jest/recommended'], 41 | rules: { 42 | 'import/no-extraneous-dependencies': [ 43 | 'off', 44 | { devDependencies: ['**/?(*.)+(spec|test).[jt]s'] }, 45 | ], 46 | }, 47 | }, 48 | ], 49 | ignorePatterns: ['**/*.js', 'node_modules', '.turbo', 'dist', 'coverage'], 50 | } 51 | -------------------------------------------------------------------------------- /packages/config/jest-common.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | resetMocks: true, 3 | moduleDirectories: ['node_modules'] 4 | } 5 | -------------------------------------------------------------------------------- /packages/config/jest-next.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('./jest-common'), 3 | testEnvironment: 'jsdom', 4 | setupFilesAfterEnv: ['@testing-library/jest-dom'], 5 | collectCoverageFrom: ['**/src/**/*.{js,ts,jsx,tsx}'], 6 | moduleFileExtensions: ['js', 'jsx', 'json', 'ts', 'tsx'], 7 | transform: { 8 | '^.+\\.tsx?$': 'esbuild-jest', 9 | '^.+\\.jsx?$': 'esbuild-jest', 10 | }, 11 | coveragePathIgnorePatterns: [], 12 | coverageThreshold: null, 13 | } 14 | -------------------------------------------------------------------------------- /packages/config/jest-server.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('./jest-common'), 3 | testEnvironment: 'node', 4 | setupFilesAfterEnv: ['@testing-library/jest-dom'], 5 | collectCoverageFrom: ['src/**/*.{js,ts}'], 6 | moduleFileExtensions: ['js', 'json', 'ts'], 7 | transform: { 8 | '^.+\\.ts$': 'esbuild-jest', 9 | '^.+\\.js$': 'esbuild-jest', 10 | }, 11 | coveragePathIgnorePatterns: [], 12 | coverageThreshold: null, 13 | } 14 | -------------------------------------------------------------------------------- /packages/config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "config", 3 | "version": "0.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "files": [ 7 | "eslint-next.js", 8 | "eslint-server.js", 9 | "jest-next.js", 10 | "jest-server.js" 11 | ], 12 | "dependencies": { 13 | "@typescript-eslint/eslint-plugin": "^5.59.5", 14 | "@typescript-eslint/parser": "^5.59.5", 15 | "eslint-config-airbnb": "^19.0.4", 16 | "eslint-config-airbnb-base": "^15.0.0", 17 | "eslint-config-airbnb-typescript": "^17.0.0", 18 | "eslint-config-next": "^13.4.1", 19 | "eslint-config-prettier": "^8.8.0", 20 | "eslint-config-turbo": "^1.10.15", 21 | "eslint-import-resolver-typescript": "^3.5.5", 22 | "eslint-plugin-import": "^2.27.5", 23 | "eslint-plugin-jest": "^27.2.1", 24 | "eslint-plugin-jest-dom": "^4.0.3", 25 | "eslint-plugin-testing-library": "^5.10.3", 26 | "tailwindcss": "^3.3.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/config/tailwind.config.app.js: -------------------------------------------------------------------------------- 1 | const baseConfig = require('./tailwind.config.base.js') 2 | 3 | // if you have multiple apps, they can all share the same app-base config 4 | module.exports = { 5 | ...baseConfig, 6 | content: ['./**/*.{js,ts,jsx,tsx}'], 7 | theme: { 8 | ...baseConfig.theme, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/config/tailwind.config.base.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require('tailwindcss/defaultTheme') 2 | 3 | // the base config is used by all apps and web-apps 4 | 5 | module.exports = { 6 | content: [], 7 | theme: { 8 | extend: { 9 | sans: ['var(--font-montserrat)', ...defaultTheme.fontFamily.sans], 10 | display: ['var(--font-bebas-neue)', ...defaultTheme.fontFamily.sans], 11 | }, 12 | }, 13 | 14 | plugins: [ 15 | require('@tailwindcss/typography'), 16 | require('@tailwindcss/forms'), 17 | require('@tailwindcss/aspect-ratio'), 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /packages/config/tailwind.config.web.js: -------------------------------------------------------------------------------- 1 | const baseConfig = require('./tailwind.config.base.js') 2 | 3 | // if you have multiple web-apps, they can all share the web-base config 4 | module.exports = { 5 | ...baseConfig, 6 | content: ['./**/*.{js,ts,jsx,tsx}'], 7 | theme: { 8 | ...baseConfig.theme, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /packages/lib/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('config/eslint-next.js'), 3 | parserOptions: { 4 | root: true, 5 | tsconfigRootDir: __dirname, 6 | project: './tsconfig.json', 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /packages/lib/hooks/useConfirmModalStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand' 2 | 3 | import { combine } from 'zustand/middleware' 4 | 5 | type Fn = () => void 6 | type AsyncFn = () => Promise 7 | 8 | export const buttonColorClassnames = { 9 | primary: 10 | 'text-white font-semibold bg-blue-600 rounded-md border border-transparent hover:bg-green-500 focus:ring-blue-500 ', 11 | error: 12 | 'text-white bg-red-600 rounded-md border border-transparent hover:bg-red-700 focus:ring-red-500', 13 | secondary: 14 | 'text-gray-700 bg-white border border-blue-600 rounded-md hover:bg-blue-500 focus:outline-none focus:ring-blue-500', 15 | // 'secondary-800': 'text-button bg-primary-800 hover:bg-primary-600 disabled:text-primary-300', 16 | transparent: 17 | 'text-button border bg-transparent text-button bg-white hover:bg-gray-50', 18 | delete: 19 | 'text-white bg-red-600 rounded-md border border-transparent hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 ', 20 | } 21 | 22 | export type ConfirmModalState = { 23 | message: string 24 | onConfirm: undefined | Fn | AsyncFn 25 | onCancelText: string 26 | onConfirmText: string 27 | buttonColor: keyof typeof buttonColorClassnames 28 | children?: React.ReactNode 29 | } 30 | 31 | const getDefaultValues = (): ConfirmModalState => ({ 32 | message: '', 33 | onConfirm: undefined, 34 | onCancelText: 'Annuleren', 35 | onConfirmText: '', 36 | buttonColor: 'primary', 37 | children: undefined, 38 | }) 39 | 40 | export const useConfirmModalStore = create( 41 | combine(getDefaultValues(), set => ({ 42 | close: () => 43 | set({ 44 | onConfirm: undefined, 45 | message: '', 46 | onConfirmText: '', 47 | onCancelText: '', 48 | buttonColor: 'primary', 49 | children: undefined, 50 | }), 51 | set, 52 | })), 53 | ) 54 | -------------------------------------------------------------------------------- /packages/lib/hooks/useEditingState.ts: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | type EditingState = { 4 | isEditing: boolean 5 | startEditing: () => void 6 | cancelEditing: () => void 7 | } 8 | 9 | export function useEditingState(initialValue: boolean): EditingState { 10 | const [isEditing, setIsEditing] = useState(initialValue) 11 | 12 | const cancelEditing = (): void => setIsEditing(false) 13 | const startEditing = (): void => setIsEditing(true) 14 | 15 | return { isEditing, startEditing, cancelEditing } 16 | } 17 | -------------------------------------------------------------------------------- /packages/lib/next-apps/hooks/signout.ts: -------------------------------------------------------------------------------- 1 | import Session from 'supertokens-auth-react/recipe/session' 2 | 3 | export const useSignout = () => async () => { 4 | await Session.signOut() 5 | 6 | window.location.href = '/login' 7 | } 8 | -------------------------------------------------------------------------------- /packages/lib/next-apps/hooks/useScreenType.ts: -------------------------------------------------------------------------------- 1 | import { useMediaQuery } from 'react-responsive' 2 | 3 | export type ScreenTypes = 4 | | 'largeScreen' 5 | | 'mediumScreen' 6 | | 'smallScreen' 7 | | 'mobile' 8 | 9 | export const useScreenType = () => { 10 | const isLargeScreen = useMediaQuery({ minWidth: 1024 }) 11 | const isMediumScreen = useMediaQuery({ minWidth: 768 }) 12 | const isSmallScreen = useMediaQuery({ minWidth: 640 }) 13 | 14 | if (isLargeScreen) { 15 | return 'largeScreen' 16 | } 17 | if (isMediumScreen) { 18 | return 'mediumScreen' 19 | } 20 | if (isSmallScreen) { 21 | return 'smallScreen' 22 | } 23 | 24 | return 'mobile' 25 | } 26 | -------------------------------------------------------------------------------- /packages/lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lib", 3 | "version": "0.0.0", 4 | "main": "./index.tsx", 5 | "types": "./index.tsx", 6 | "license": "MIT", 7 | "devDependencies": { 8 | "@types/react": "18.2.21", 9 | "@types/react-dom": "18.2.14", 10 | "autoprefixer": "10.4.15", 11 | "postcss": "8.4.31", 12 | "tailwindcss": "^3.3.3", 13 | "tsconfig": "workspace:*", 14 | "typescript": "5.2.2" 15 | }, 16 | "dependencies": { 17 | "nextjs-cors": "^2.1.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["."], 4 | "exclude": ["dist", "build", "node_modules"], 5 | "compilerOptions": { 6 | "baseUrl": "." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/lib/utils/capacitor.ts: -------------------------------------------------------------------------------- 1 | import { Capacitor } from '@capacitor/core' 2 | 3 | export const useNativeOS = (): 'android' | 'ios' | 'web' => 4 | Capacitor.getPlatform() as 'android' | 'ios' | 'web' 5 | 6 | export const usePlatform = (): 'APP' | 'WEB' => 7 | Capacitor.isNativePlatform() ? 'APP' : 'WEB' 8 | 9 | // export const openAppBrowser = async (url: string) => { 10 | // await Browser.open({ url, toolbarColor: '#bae6fd' }) 11 | // } 12 | 13 | // export const pickImages = async ({ limit }: { limit: number }) => { 14 | // const images = await Camera.pickImages({ 15 | // quality: 100, 16 | // limit, 17 | // }) 18 | 19 | // return images 20 | // } 21 | -------------------------------------------------------------------------------- /packages/lib/utils/common.types.ts: -------------------------------------------------------------------------------- 1 | export type Platform = 'WEB' | 'APP' | 'ALL' 2 | 3 | /** 4 | * Used to swap recipes that SuperTokens uses to provide auth functionality 5 | * 6 | * emailpassword: Simple email + password based login 7 | * thirdparty: Social login (Google, Apple etc) 8 | * thirdpartyemailpassword: Combination of emailpassword and thirdparty 9 | * passwordless: Passwordless login a code (sent via email by default but configurable) 10 | * thirdpartypasswordless: Combination of thirdparty and passwordless 11 | */ 12 | export type AuthMode = 13 | | 'thirdparty' 14 | | 'passwordless' 15 | | 'thirdpartypasswordless' 16 | | 'emailpassword' 17 | | 'thirdpartyemailpassword' 18 | 19 | // todo: I have to change the registration flow to support email password, also requires lost pass flow 20 | -------------------------------------------------------------------------------- /packages/lib/utils/config.ts: -------------------------------------------------------------------------------- 1 | import { AuthMode } from './common.types' 2 | 3 | export const PROD_URL_NO_HTTPS = 'nextjs-native-starter-app.vercel.app' 4 | 5 | export const IS_IN_PRODUCTION_ENVIRONMENT = 6 | process.env.NEXT_PUBLIC_APP_STAGE !== 'development' 7 | 8 | // if you want to test social auth on your native device, set the API server to be your local IP address (so instead of http://localhost:3001, it would be http://000.000.0.0:3001) 9 | export const FRONTEND_URL = !IS_IN_PRODUCTION_ENVIRONMENT 10 | ? 'http://localhost:3001' 11 | : `https://${PROD_URL_NO_HTTPS}` 12 | 13 | // Make sure to change this to your own unique URL 14 | export const APP_BUNDLE_URL = `next.supertokens.app` // used to create the deep link 15 | 16 | export const REDIRECT_URL = !IS_IN_PRODUCTION_ENVIRONMENT 17 | ? FRONTEND_URL 18 | : 'https://nextjs-native-starter-app-git-main-robschilderr.vercel.app' 19 | 20 | export const APP_ORIGIN_URLS = [ 21 | 'capacitor://localhost', 22 | 'http://localhost', 23 | 'https://localhost', 24 | 'ionic://localhost', 25 | `ionic://${FRONTEND_URL.split('://')[1]}`, 26 | `next.supertokens.app`, 27 | 'capacitor://', 28 | `capacitor://${FRONTEND_URL.split('://')[1]}`, 29 | `http://${FRONTEND_URL.split('://')[1]}`, 30 | ] 31 | 32 | export const ALLOWED_CORS_URLS = [ 33 | ...APP_ORIGIN_URLS, 34 | 'capacitor://nextjs-native.dev', 35 | 'http://localhost:3000', 36 | 'http://localhost:3001', 37 | 'https://www.nextjs-native.dev', 38 | 'https://nextjs-native.dev', 39 | 'https://nextjs-native-git-main-robschilderr.vercel.app', 40 | 'http://localhost', 41 | ] 42 | 43 | export const AUTH_MODE: AuthMode = 'thirdpartypasswordless' 44 | -------------------------------------------------------------------------------- /packages/lib/utils/cors.ts: -------------------------------------------------------------------------------- 1 | import NextCors from 'nextjs-cors' 2 | import { NextApiRequest, NextApiResponse } from 'next' 3 | import supertokens from 'supertokens-node' 4 | import { ALLOWED_CORS_URLS } from './config' 5 | 6 | // * 4. Important Capacitor note: 7 | // * This authCors function is created to set up CORS configurations for Next.js API routes. 8 | // * It is essential to call this function at the beginning of every API route. 9 | // * The reason is that Capacitor, unlike traditional browsers, makes requests with different origin addresses. 10 | // * For example, on an iPhone, the origin is "capacitor://localhost", while on an Android, it is "http://localhost". 11 | // * 12 | // * In the "capacitor.config" file, the server object allows you to change the hostname for Capacitor and specify a live-reload URL: 13 | // * 14 | // * server: { 15 | // * url: 'http://192.168.1.7:2001', 16 | // * cleartext: true, 17 | // * hostname: 'yourPRODurl', // Recommended for compatibility with Web APIs that require a secure context 18 | // * }, 19 | // * 20 | // * It is recommended to keep the hostname as its default to ensure compatibility with Web APIs that would otherwise 21 | // * require a secure context, such as navigator.geolocation and MediaDevices.getUserMedia. 22 | // * 23 | // * When you add a live-reload URL in the server object, the domain changes accordingly. 24 | // * 25 | // * By specifying and including allowed origins in the ALLOWED_CORS_URLS array, we ensure that our 26 | // * API routes are accessible only from the specified origins, which include Capacitor configurations, 27 | // * local development environments, and deployed apps on various domains. 28 | // * If experiencing CORS isues on Vercel: make sure that your website has no 'www' in the domain name, or change the config to include it. 29 | 30 | export const authCors = async (req: NextApiRequest, res: NextApiResponse) => { 31 | await NextCors(req, res, { 32 | methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'], 33 | origin: ALLOWED_CORS_URLS, 34 | credentials: true, 35 | allowedHeaders: ['content-type', ...supertokens.getAllCORSHeaders()], 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /packages/lib/utils/handleRegister.ts: -------------------------------------------------------------------------------- 1 | import { signupWithEmailPassword } from './supertokensUtilities' 2 | 3 | export const handleRegister = async ({ 4 | email, 5 | password, 6 | }: { 7 | email: string 8 | password: string 9 | }) => { 10 | try { 11 | const superTokensResponse = await signupWithEmailPassword({ 12 | email: email.toLowerCase().trim(), 13 | password, 14 | }) 15 | 16 | // if (superTokensResponse !== 'OK') { 17 | // throw new Error('Error creating Supertokens account') 18 | // } 19 | return superTokensResponse 20 | } catch (err: any) { 21 | // handle error 22 | console.log({ err }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/lib/utils/logError.ts: -------------------------------------------------------------------------------- 1 | // import { captureException as captureExceptionNextJS } from '@sentry/nextjs' 2 | // import { captureException as captureExceptionCapacitor } from '@sentry/capacitor' 3 | // import { Capacitor } from '@capacitor/core' 4 | 5 | // TODO: fix that all Errors are logged as type Error 6 | // TODO: Waiting for sentry cap v5 7 | 8 | // type Error = { 9 | // message: string 10 | // data?: any 11 | // } 12 | 13 | export const logError = (err: any, extra?: Record) => { 14 | if (process.env.NEXT_PUBLIC_APP_STAGE === 'development') { 15 | console.error(err) 16 | } 17 | 18 | // if (typeof window !== 'undefined') { 19 | // if (Capacitor.isNative) { 20 | // captureExceptionCapacitor(err) 21 | // } else { 22 | // captureExceptionNextJS(err, extra) 23 | // } 24 | } 25 | -------------------------------------------------------------------------------- /packages/lib/utils/navLinks.ts: -------------------------------------------------------------------------------- 1 | import { 2 | HomeIcon, 3 | CogIcon, 4 | InformationCircleIcon, 5 | FolderIcon, 6 | } from '@heroicons/react/24/outline' 7 | 8 | export const navLinks = [ 9 | { 10 | href: '/', 11 | name: 'Address Info', 12 | icon: HomeIcon, 13 | subNavLinks: [], 14 | backgroundColor: 'blue', 15 | }, 16 | { 17 | href: '/settings', 18 | name: 'General settings', 19 | icon: CogIcon, 20 | subNavLinks: [], 21 | backgroundColor: 'gray', 22 | }, 23 | { 24 | href: '/about', 25 | name: 'About', 26 | icon: InformationCircleIcon, 27 | subNavLinks: [], 28 | backgroundColor: 'blue', 29 | }, 30 | { 31 | href: '/privacy', 32 | name: 'Privacy Policy', 33 | icon: FolderIcon, 34 | subNavLinks: [], 35 | backgroundColor: 'purple', 36 | }, 37 | { 38 | href: '/terms', 39 | name: 'Terms of Service', 40 | icon: FolderIcon, 41 | subNavLinks: [], 42 | backgroundColor: 'purple', 43 | }, 44 | ] 45 | 46 | // get the type of navLinks 47 | 48 | export type NavLink = (typeof navLinks)[0] 49 | 50 | export type NavLinks = typeof navLinks 51 | -------------------------------------------------------------------------------- /packages/lib/utils/supertokensNodeUtilities.ts: -------------------------------------------------------------------------------- 1 | import supertokens from 'supertokens-node' 2 | 3 | export const getUserById = async (userId: string) => supertokens.getUser(userId) 4 | -------------------------------------------------------------------------------- /packages/lib/utils/util.ts: -------------------------------------------------------------------------------- 1 | import { twMerge } from 'tailwind-merge' 2 | import { ClassValue, clsx } from 'clsx' 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | export const getInitialNameAvatar = (name?: string | null, color?: string) => 8 | `https://ui-avatars.com/api/?background=${color || '0D8ABC'}&color=fff&name=${ 9 | name || '' 10 | }` 11 | 12 | export function truncateString( 13 | str: string, 14 | maxLen: number, 15 | ): { 16 | value: string 17 | isTruncated: boolean 18 | } { 19 | if (!str) { 20 | return { 21 | value: '', 22 | isTruncated: false, 23 | } 24 | } 25 | return { 26 | value: str.length <= maxLen ? str : `${str.slice(0, maxLen)}...`, 27 | isTruncated: !(str.length <= maxLen), 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/tsconfig/README.md: -------------------------------------------------------------------------------- 1 | # `tsconfig` 2 | 3 | These are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from. 4 | -------------------------------------------------------------------------------- /packages/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "allowJs": true, 6 | "composite": false, 7 | "declaration": true, 8 | "declarationMap": true, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "incremental": true, 12 | "inlineSources": false, 13 | "isolatedModules": true, 14 | "lib": ["ES2021", "DOM", "DOM.Iterable"], 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "noUnusedLocals": false, 18 | "noUnusedParameters": false, 19 | "preserveWatchOutput": true, 20 | "resolveJsonModule": true, 21 | "skipLibCheck": true, 22 | "strict": true, 23 | "typeRoots": ["../../node_modules/@types"] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/tsconfig/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "jsx": "react-jsx", 7 | "noEmit": true, 8 | "target": "es5" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsconfig", 3 | "version": "0.0.0", 4 | "private": true, 5 | "main": "index.js", 6 | "files": [ 7 | "base.json", 8 | "nextjs.json", 9 | "react-library.json" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/tsconfig/server.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Server", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "target": "es6", 7 | "noEmit": false, 8 | "module": "commonjs", 9 | "sourceMap": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('config/eslint-next.js'), 3 | parserOptions: { 4 | tsconfigRootDir: __dirname, 5 | project: './tsconfig.json', 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /packages/ui/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const Button = () => { 4 | return ( 5 | 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/components/AuthLayout.tsx: -------------------------------------------------------------------------------- 1 | export const AuthLogo = () => ( 2 |

6 | {' '} 7 | Next.js 8 | Native 🏄 9 |

10 | ) 11 | 12 | export const AuthLayout = ({ children }: any) => ( 13 | <> 14 |