diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..be3f7b2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff --git a/apps/api/package.json b/apps/api/package.json
index 904b358..d73b571 100644
--- a/apps/api/package.json
+++ b/apps/api/package.json
@@ -2,6 +2,7 @@
"name": "@jiobase/api",
"version": "0.0.1",
"private": true,
+ "license": "AGPL-3.0-only",
"type": "module",
"scripts": {
"dev": "wrangler dev --port 8788",
diff --git a/apps/proxy/package.json b/apps/proxy/package.json
index b44da4f..04d0f73 100644
--- a/apps/proxy/package.json
+++ b/apps/proxy/package.json
@@ -2,6 +2,7 @@
"name": "@jiobase/proxy",
"version": "0.0.1",
"private": true,
+ "license": "AGPL-3.0-only",
"type": "module",
"scripts": {
"dev": "wrangler dev",
diff --git a/apps/proxy/src/config.ts b/apps/proxy/src/config.ts
index 78d3d5c..2e8c698 100644
--- a/apps/proxy/src/config.ts
+++ b/apps/proxy/src/config.ts
@@ -1,5 +1,9 @@
import type { Env, ProxyConfig } from './types.js';
+// Cache KV reads for 60 seconds — avoids hitting KV on every single request.
+// Config updates (from the API) take up to 60s to propagate, which is acceptable.
+const KV_CACHE_TTL = 60;
+
export async function resolveConfig(
hostname: string,
env: Env
@@ -19,17 +23,17 @@ export async function resolveConfig(
}
if (slug) {
- // Look up by slug
- const raw = await env.PROXY_CONFIG.get(`app:${slug}`);
+ // Look up by slug with caching
+ const raw = await env.PROXY_CONFIG.get(`app:${slug}`, { cacheTtl: KV_CACHE_TTL });
if (!raw) return null;
return { config: JSON.parse(raw), slug };
}
// Otherwise, check custom domain mapping
- const mappedSlug = await env.PROXY_CONFIG.get(`domain:${hostname}`);
+ const mappedSlug = await env.PROXY_CONFIG.get(`domain:${hostname}`, { cacheTtl: KV_CACHE_TTL });
if (!mappedSlug) return null;
- const raw = await env.PROXY_CONFIG.get(`app:${mappedSlug}`);
+ const raw = await env.PROXY_CONFIG.get(`app:${mappedSlug}`, { cacheTtl: KV_CACHE_TTL });
if (!raw) return null;
return { config: JSON.parse(raw), slug: mappedSlug };
}
diff --git a/apps/proxy/src/handler.ts b/apps/proxy/src/handler.ts
index 935438d..38e90a3 100644
--- a/apps/proxy/src/handler.ts
+++ b/apps/proxy/src/handler.ts
@@ -52,13 +52,25 @@ export async function handleHttpProxy(
// Clone response headers
const responseHeaders = new Headers(upstreamResponse.headers);
- // Rewrite supabase.co URLs in Location headers (redirects)
+ // Rewrite Location headers that redirect directly to the Supabase host.
+ // Only rewrite the *host* portion of the URL — NOT query params.
+ // This avoids breaking OAuth redirect_uri params (e.g. Google's redirect_uri
+ // must match exactly between the authorize request and the token exchange).
const location = responseHeaders.get('Location');
- if (location && location.includes('.supabase.co')) {
- responseHeaders.set(
- 'Location',
- location.replace(new URL(config.supabaseUrl).hostname, url.hostname)
- );
+ if (location) {
+ try {
+ const locUrl = new URL(location);
+ const supabaseHost = new URL(config.supabaseUrl).hostname;
+ if (locUrl.hostname === supabaseHost) {
+ // Direct redirect to Supabase — rewrite host to proxy
+ locUrl.hostname = url.hostname;
+ responseHeaders.set('Location', locUrl.toString());
+ }
+ // If Location points to an external host (e.g. accounts.google.com),
+ // leave it untouched — including any redirect_uri query params.
+ } catch {
+ // Malformed Location header — leave it as-is
+ }
}
// Add CORS headers
diff --git a/apps/proxy/src/websocket.ts b/apps/proxy/src/websocket.ts
index 4a272c9..eb4d3d2 100644
--- a/apps/proxy/src/websocket.ts
+++ b/apps/proxy/src/websocket.ts
@@ -9,12 +9,17 @@ export async function handleWebSocket(
upstreamUrl.pathname = url.pathname;
upstreamUrl.search = url.search;
- // Build upstream WebSocket URL
- const wsUrl = upstreamUrl.toString().replace('https:', 'wss:').replace('http:', 'ws:');
+ // Cloudflare Workers fetch() requires https:// (not wss://) for WebSocket upgrade.
+ // The Upgrade header tells the upstream to switch protocols.
+ const headers = new Headers(request.headers);
+ headers.set('Host', upstreamUrl.hostname);
+ headers.delete('cf-connecting-ip');
+ headers.delete('cf-ray');
+ headers.delete('cf-visitor');
+ headers.delete('cf-ipcountry');
- // Create upstream WebSocket connection
- const upstreamResp = await fetch(wsUrl, {
- headers: request.headers,
+ const upstreamResp = await fetch(upstreamUrl.toString(), {
+ headers,
});
const upstreamWs = upstreamResp.webSocket;
diff --git a/apps/web/package.json b/apps/web/package.json
index 9f5d5f3..e809695 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -1,6 +1,7 @@
{
"name": "@jiobase/web",
"private": true,
+ "license": "AGPL-3.0-only",
"version": "0.0.1",
"type": "module",
"scripts": {
diff --git a/apps/web/src/lib/components/AuthorBio.svelte b/apps/web/src/lib/components/AuthorBio.svelte
new file mode 100644
index 0000000..00b8c4e
--- /dev/null
+++ b/apps/web/src/lib/components/AuthorBio.svelte
@@ -0,0 +1,63 @@
+
+
+
+ Traffic is now routing through Cloudflare's edge network. Your users won't even notice a difference — except that everything works now.
+
+
+
+
+ Hey, I'm Sunith — I built JioBase because the Supabase block broke my own app and I knew other devs were stuck too. It's free because no one should pay to fix someone else's problem.
+
+
+ But Cloudflare bills are real. If JioBase just saved your production app, a $3 coffee helps me keep the lights on for everyone.
+
+
+ {:else}
+
+
+
+ ☕
+
+
Quick reality check
+
+
+
+ JioBase proxies millions of requests for free. Every single request costs me money.
+
+
+
+ I'm not a company. I'm one developer paying Cloudflare bills out of pocket so your Supabase app works in India.
+
+
+
+ ☕
+
+ $3 = one coffee = JioBase stays free for hundreds of devs
+
+
+
+
+ No pressure — but it genuinely helps keep this project alive.
+
+
diff --git a/apps/web/src/lib/data/seo-pages.ts b/apps/web/src/lib/data/seo-pages.ts
new file mode 100644
index 0000000..78a87e1
--- /dev/null
+++ b/apps/web/src/lib/data/seo-pages.ts
@@ -0,0 +1,889 @@
+// ============================================================
+// SEO Pages Data - Central data store for programmatic pages
+// ============================================================
+
+// === Types ===
+
+export interface FaqItem {
+ question: string;
+ answer: string;
+}
+
+export interface RelatedPage {
+ title: string;
+ description: string;
+ href: string;
+ badge: string;
+ badgeColor: string;
+}
+
+export interface IspPageData {
+ type: 'isp';
+ slug: string;
+ name: string;
+ shortName: string;
+ subscribers: string;
+ networkTypes: string[];
+ blockConfirmed: boolean;
+ blockType: string;
+ servicesBlocked: string[];
+ dnsWorkaroundWorks: boolean;
+ whatHappened: string;
+ howTheyBlock: string;
+ diagnosticCommand: string;
+ additionalNotes: string;
+ faqs: FaqItem[];
+ relatedPages: RelatedPage[];
+ metaTitle: string;
+ metaDescription: string;
+ metaKeywords: string;
+}
+
+export interface ErrorPageData {
+ type: 'error';
+ slug: string;
+ errorCode: string;
+ displayName: string;
+ whatItMeans: string;
+ whyItHappens: string;
+ diagnosticSteps: { step: string; command: string; expected: string }[];
+ faqs: FaqItem[];
+ relatedPages: RelatedPage[];
+ metaTitle: string;
+ metaDescription: string;
+ metaKeywords: string;
+}
+
+export interface FeaturePageData {
+ type: 'feature';
+ slug: string;
+ featureName: string;
+ shortName: string;
+ supabasePath: string;
+ whatBreaks: string;
+ userImpact: string;
+ codeExample: string;
+ codeFilename: string;
+ faqs: FaqItem[];
+ relatedPages: RelatedPage[];
+ metaTitle: string;
+ metaDescription: string;
+ metaKeywords: string;
+}
+
+export interface FrameworkPageData {
+ slug: string;
+ name: string;
+ shortName: string;
+ language: string;
+ envPrefix: string;
+ initFile: string;
+ envFile: string;
+ codeBefore: string;
+ codeAfter: string;
+ packageManager: string;
+ additionalSteps: string[];
+ faqs: FaqItem[];
+ relatedGuides: RelatedPage[];
+ metaTitle: string;
+ metaDescription: string;
+ metaKeywords: string;
+}
+
+export type FixPageData = IspPageData | ErrorPageData | FeaturePageData;
+
+// === ISP Pages Data ===
+
+export const ISP_PAGES: IspPageData[] = [
+ {
+ type: 'isp',
+ slug: 'jio',
+ name: 'Reliance Jio',
+ shortName: 'Jio',
+ subscribers: '500M+',
+ networkTypes: ['4G mobile data', '5G mobile data', 'JioFiber broadband'],
+ blockConfirmed: true,
+ blockType: 'DNS poisoning with possible DPI',
+ servicesBlocked: ['*.supabase.co (all Supabase services)'],
+ dnsWorkaroundWorks: true,
+ whatHappened: 'Reliance Jio, India\'s largest telecom operator with over 500 million subscribers, began DNS-blocking all *.supabase.co domains in February 2026. The block was issued under Section 69A of the IT Act through a government ministry order. Jio\'s DNS resolvers return a sinkhole IP (49.44.79.236) instead of the actual Supabase AWS servers, making all Supabase API calls fail silently. This affects every Jio user - both mobile data and JioFiber broadband customers.',
+ howTheyBlock: 'Jio uses DNS poisoning as the primary blocking mechanism. When a Jio user\'s device queries *.supabase.co, Jio\'s internal DNS resolvers return a Jio-owned IP address instead of the real Supabase server IP. This causes all HTTP and WebSocket connections to time out. Some users report that changing DNS to 1.1.1.1 or 8.8.8.8 restores access for development, but this does not fix the issue for your end users who are on Jio\'s default DNS. There are also reports of deep packet inspection (DPI) being used alongside DNS poisoning on some Jio networks.',
+ diagnosticCommand: '# Check if Jio is blocking Supabase DNS\nnslookup your-project.supabase.co\n# If blocked: returns 49.44.79.236 (Jio sinkhole)\n# If working: returns an AWS IP like 13.233.x.x\n\n# Compare with Google DNS\nnslookup your-project.supabase.co 8.8.8.8\n# Should return the real AWS IP\n\n# Test HTTP connectivity\ncurl -I https://your-project.supabase.co/rest/v1/ \\\n -H "apikey: YOUR_ANON_KEY"',
+ additionalNotes: 'Jio is the most impactful block because it serves the largest subscriber base in India. If your app serves Indian users, there is a very high probability that a significant portion of your users are on Jio. The block affects both JioFiber broadband and Jio mobile data connections.',
+ faqs: [
+ {
+ question: 'Is Supabase blocked on all Jio connections?',
+ answer: 'Yes. The block affects Jio 4G/5G mobile data and JioFiber broadband connections across India. Some regions may experience the block at different times due to how Jio rolls out DNS changes, but as of February 2026, the block is confirmed nationwide.'
+ },
+ {
+ question: 'Will changing DNS to 1.1.1.1 fix it for my users?',
+ answer: 'No. Changing DNS only fixes it on your own device for development purposes. Your end users on Jio will still be using Jio\'s default DNS resolvers and will not be able to reach *.supabase.co. You need a reverse proxy that routes traffic through an unblocked domain.'
+ },
+ {
+ question: 'Does the Jio block affect Supabase Realtime/WebSockets?',
+ answer: 'Yes. The DNS block affects all traffic to *.supabase.co, including REST API, Auth, Storage, Realtime WebSocket connections, and Edge Functions. Everything that connects to the supabase.co domain is blocked.'
+ },
+ {
+ question: 'How quickly can I fix my Jio-blocked app?',
+ answer: 'With JioBase, you can fix it in under 5 minutes. Create a free account at jiobase.com/register, set up a proxy app, and swap your Supabase URL - one line of code. Your Jio users will be able to access your app immediately.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Fix on Airtel', description: 'Supabase is also blocked on Airtel networks', href: '/fix/airtel', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Fix on ACT Fibernet', description: 'ACT Fibernet users are affected too', href: '/fix/act', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'ERR_CONNECTION_TIMED_OUT', description: 'Understand the timeout error you see', href: '/fix/err-connection-timed-out', badge: 'Error', badgeColor: 'red' },
+ { title: 'Full fix guide', description: 'Detailed blog post on the Supabase block', href: '/blog/supabase-blocked-india-fix', badge: 'Blog', badgeColor: 'blue' }
+ ],
+ metaTitle: 'Supabase Blocked on Jio - Fix It in 5 Minutes | JioBase',
+ metaDescription: 'Supabase is DNS-blocked on Reliance Jio (4G, 5G, JioFiber). Fix your app for 500M+ Jio users with a one-line proxy change. No VPN needed.',
+ metaKeywords: 'supabase blocked jio, supabase jio fix, supabase not working jio, jiofiber supabase blocked, supabase dns block jio'
+ },
+ {
+ type: 'isp',
+ slug: 'airtel',
+ name: 'Bharti Airtel',
+ shortName: 'Airtel',
+ subscribers: '380M+',
+ networkTypes: ['4G mobile data', '5G mobile data', 'Airtel Xstream Fiber broadband'],
+ blockConfirmed: true,
+ blockType: 'DNS poisoning',
+ servicesBlocked: ['*.supabase.co (all Supabase services)'],
+ dnsWorkaroundWorks: true,
+ whatHappened: 'Bharti Airtel, India\'s second-largest telecom operator, joined the Supabase block following the same government ministry order under Section 69A. Airtel\'s DNS resolvers redirect *.supabase.co queries to incorrect IPs, causing connection timeouts for all Supabase API calls. This affects Airtel\'s 380 million+ subscribers across both mobile data and broadband connections.',
+ howTheyBlock: 'Airtel implements the block through DNS poisoning. Their DNS resolvers return incorrect IP addresses for *.supabase.co domains, preventing connections from reaching Supabase\'s actual servers. Unlike Jio, Airtel has not been reported to use deep packet inspection - switching to an alternative DNS like Google (8.8.8.8) or Cloudflare (1.1.1.1) typically restores access on individual devices for development.',
+ diagnosticCommand: '# Check if Airtel is blocking Supabase DNS\nnslookup your-project.supabase.co\n# If blocked: returns incorrect IP\n# If working: returns AWS IP\n\n# Test with Google DNS\nnslookup your-project.supabase.co 8.8.8.8\n\n# Test HTTP connectivity\ncurl -m 5 https://your-project.supabase.co/rest/v1/ \\\n -H "apikey: YOUR_ANON_KEY" 2>&1 | head -5',
+ additionalNotes: 'Airtel is India\'s second-largest ISP. Combined with Jio, the block affects over 880 million internet subscribers. If your app targets the Indian market, you cannot rely on *.supabase.co being accessible.',
+ faqs: [
+ {
+ question: 'Is Supabase blocked on Airtel broadband and mobile?',
+ answer: 'Yes. Both Airtel mobile data (4G/5G) and Airtel Xstream Fiber broadband connections are affected. The DNS poisoning is applied at the network level, so all connection types are impacted.'
+ },
+ {
+ question: 'Does changing DNS fix Supabase on Airtel?',
+ answer: 'For your own device (development), yes - switching to Google DNS (8.8.8.8) or Cloudflare (1.1.1.1) typically works on Airtel. But this does not fix the problem for your end users. They will still be on Airtel\'s default DNS. You need a reverse proxy solution.'
+ },
+ {
+ question: 'Is Airtel also blocking Firebase?',
+ answer: 'As of February 2026, Firebase is not blocked on Airtel. The Firebase block is primarily on BSNL networks. However, this could change at any time - the same Section 69A mechanism could be used to block any domain on any ISP.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Fix on Jio', description: 'Jio is the largest affected ISP', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Fix on BSNL', description: 'BSNL has separate Firebase blocks', href: '/fix/bsnl', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Test if blocked', description: 'Diagnose ISP blocks step by step', href: '/blog/test-if-backend-blocked-india', badge: 'Blog', badgeColor: 'blue' },
+ { title: 'Proxy tutorial', description: 'Build your own Cloudflare Worker proxy', href: '/blog/proxy-supabase-cloudflare-workers', badge: 'Tutorial', badgeColor: 'purple' }
+ ],
+ metaTitle: 'Supabase Blocked on Airtel - Fix It in 5 Minutes | JioBase',
+ metaDescription: 'Supabase is DNS-blocked on Bharti Airtel (mobile and broadband). Fix your app for 380M+ Airtel users with a one-line proxy change.',
+ metaKeywords: 'supabase blocked airtel, supabase airtel fix, supabase not working airtel, airtel supabase dns block'
+ },
+ {
+ type: 'isp',
+ slug: 'bsnl',
+ name: 'BSNL',
+ shortName: 'BSNL',
+ subscribers: '100M+',
+ networkTypes: ['Bharat Fiber broadband', 'Mobile data', 'FTTH'],
+ blockConfirmed: true,
+ blockType: 'DNS poisoning',
+ servicesBlocked: ['*.supabase.co (Supabase)', 'Some Firebase endpoints'],
+ dnsWorkaroundWorks: true,
+ whatHappened: 'BSNL, India\'s state-owned telecom operator, has a history of blocking developer platforms. In August 2025, BSNL blocked several developer tools including raw GitHub content, certain Firebase endpoints, and other SaaS APIs. BSNL has also implemented the Supabase block following the ministry order. Additionally, BSNL is the primary ISP where Firebase services are blocked, making it the only major ISP where both Firebase and Supabase are unreachable.',
+ howTheyBlock: 'BSNL uses DNS poisoning similar to other ISPs. Their resolvers return incorrect addresses for blocked domains. BSNL\'s blocking has historically been inconsistent across regions - users in some cities may have access while others do not. Switching DNS typically restores access for development purposes.',
+ diagnosticCommand: '# Check BSNL DNS resolution\nnslookup your-project.supabase.co\n\n# Test with Cloudflare DNS\nnslookup your-project.supabase.co 1.1.1.1\n\n# Also test Firebase (blocked on BSNL)\nnslookup firebaseio.com\nnslookup firebaseio.com 1.1.1.1',
+ additionalNotes: 'BSNL is the only major Indian ISP where both Supabase AND Firebase are blocked. If your app uses either backend and serves BSNL users, a proxy is essential. BSNL\'s blocking is often inconsistent across regions.',
+ faqs: [
+ {
+ question: 'Is both Firebase and Supabase blocked on BSNL?',
+ answer: 'Yes. BSNL is unique in blocking both platforms. Firebase endpoints have been blocked since August 2025, and Supabase was added to the block list in February 2026. This makes BSNL the most restrictive ISP for developers using BaaS platforms.'
+ },
+ {
+ question: 'Why does BSNL block more services than other ISPs?',
+ answer: 'As a government-owned telecom operator, BSNL tends to implement blocking orders more aggressively. BSNL was also the first ISP to block several developer tools in August 2025, including raw GitHub content and Telegram-related domains.'
+ },
+ {
+ question: 'Can JioBase fix both Firebase and Supabase on BSNL?',
+ answer: 'JioBase is specifically designed for Supabase proxying - it handles REST, Auth, Storage, Realtime, and Edge Functions. For Firebase, you would need a separate Cloudflare Worker proxy. Our Worker Generator Tool can help you get started with a DIY proxy for Firebase.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Firebase + Supabase crisis', description: 'Both backends blocked in India', href: '/blog/firebase-supabase-blocked-india', badge: 'Blog', badgeColor: 'red' },
+ { title: 'Fix on Jio', description: 'Largest affected ISP', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Supabase alternatives', description: 'Compare backend options', href: '/blog/supabase-alternatives-india', badge: 'Comparison', badgeColor: 'purple' },
+ { title: 'DIY Worker proxy', description: 'Build your own proxy', href: '/tools/worker-generator', badge: 'Tool', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Supabase & Firebase Blocked on BSNL - Fix Both | JioBase',
+ metaDescription: 'BSNL blocks both Supabase and Firebase. Fix your app for BSNL users with a reverse proxy. Works for all BSNL connections - Bharat Fiber, mobile, FTTH.',
+ metaKeywords: 'supabase blocked bsnl, firebase blocked bsnl, bsnl blocking developer tools, bsnl supabase fix'
+ },
+ {
+ type: 'isp',
+ slug: 'act',
+ name: 'ACT Fibernet',
+ shortName: 'ACT',
+ subscribers: '2M+',
+ networkTypes: ['Fiber broadband'],
+ blockConfirmed: true,
+ blockType: 'DNS poisoning',
+ servicesBlocked: ['*.supabase.co (all Supabase services)'],
+ dnsWorkaroundWorks: true,
+ whatHappened: 'ACT Fibernet, a popular broadband provider in major Indian cities like Bengaluru, Hyderabad, Chennai, and Delhi, confirmed the Supabase block following the ministry order. However, the block has been inconsistent - TechCrunch verified that supabase.co was inaccessible on ACT in Delhi but some users in Bengaluru reported it still worked. This inconsistency is typical of how Indian ISPs implement blocking orders.',
+ howTheyBlock: 'ACT Fibernet uses DNS-level blocking. Their DNS resolvers intercept queries for *.supabase.co and return incorrect results. The implementation appears to be region-dependent, with some ACT networks implementing the block before others.',
+ diagnosticCommand: '# Check ACT Fibernet DNS\nnslookup your-project.supabase.co\n\n# Compare with Cloudflare DNS\nnslookup your-project.supabase.co 1.1.1.1\n\n# Quick HTTP test\ncurl -m 5 -s -o /dev/null -w "%{http_code}" \\\n https://your-project.supabase.co/rest/v1/ \\\n -H "apikey: YOUR_ANON_KEY"',
+ additionalNotes: 'ACT Fibernet is popular among tech professionals and developers in Tier-1 cities. The inconsistent blocking means your app may work for some ACT users but not others, making it especially frustrating to debug.',
+ faqs: [
+ {
+ question: 'Is Supabase blocked on all ACT Fibernet connections?',
+ answer: 'The block is inconsistent across ACT regions. Users in Delhi and some other cities have confirmed the block, while some users in Bengaluru reported intermittent access. If your app serves ACT users, you should assume the block can appear at any time in any region.'
+ },
+ {
+ question: 'Does ACT Fibernet block Firebase too?',
+ answer: 'No. As of February 2026, Firebase works on ACT Fibernet. The Firebase block is primarily on BSNL. However, given ACT\'s compliance with the Supabase ministry order, future blocking of other services is possible.'
+ },
+ {
+ question: 'My Supabase app works on ACT but my users say it does not. Why?',
+ answer: 'ACT\'s block rollout is region-dependent. Your ACT connection may not be affected yet while your users in a different city are blocked. Always test from multiple networks and consider adding a proxy proactively.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Fix on Jio', description: 'Block confirmed on India\'s largest ISP', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Fix on Airtel', description: 'Block confirmed on Airtel too', href: '/fix/airtel', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Test if blocked', description: 'Step-by-step ISP block diagnosis', href: '/blog/test-if-backend-blocked-india', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'India status', description: 'Check live block status', href: '/india-status', badge: 'Status', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Supabase Blocked on ACT Fibernet - How to Fix | JioBase',
+ metaDescription: 'ACT Fibernet is blocking Supabase in some Indian cities. Fix your app for ACT users with a one-line proxy change. No VPN needed.',
+ metaKeywords: 'supabase blocked act fibernet, act fibernet supabase fix, supabase not working act broadband'
+ },
+ {
+ type: 'isp',
+ slug: 'vodafone-idea',
+ name: 'Vodafone Idea (Vi)',
+ shortName: 'Vi',
+ subscribers: '230M+',
+ networkTypes: ['4G mobile data', 'Vi-Fi broadband'],
+ blockConfirmed: false,
+ blockType: 'Potential DNS blocking - unconfirmed',
+ servicesBlocked: ['*.supabase.co (reports vary)'],
+ dnsWorkaroundWorks: true,
+ whatHappened: 'Vodafone Idea (now branded as Vi) has not been officially confirmed as blocking Supabase. However, given that the ministry order applies to all ISPs licensed in India, Vi may implement the block at any time. Some users have reported intermittent access issues on Vi networks, but these have not been consistently reproduced.',
+ howTheyBlock: 'If Vi implements the block, it would likely use DNS poisoning similar to Jio and Airtel. Vi has historically been slower to implement blocking orders compared to larger ISPs.',
+ diagnosticCommand: '# Test Vi DNS resolution\nnslookup your-project.supabase.co\n\n# Compare with public DNS\nnslookup your-project.supabase.co 8.8.8.8\n\n# Test connectivity\ncurl -m 10 https://your-project.supabase.co/rest/v1/ \\\n -H "apikey: YOUR_ANON_KEY" -v 2>&1 | grep -i "connect"',
+ additionalNotes: 'Even if Vi has not yet implemented the block, proactively adding a proxy protects your app against the possibility. The ministry order applies to all ISPs, so it is a matter of when, not if.',
+ faqs: [
+ {
+ question: 'Is Supabase definitely blocked on Vi?',
+ answer: 'As of February 2026, the block on Vi is not confirmed. However, the government ministry order applies to all Indian ISPs. Vi may implement the block at any time. Proactively adding a proxy is the safest approach.'
+ },
+ {
+ question: 'Should I add a proxy even if Vi is not blocking yet?',
+ answer: 'Yes. The ministry order under Section 69A applies to all ISPs. Even if Vi has not implemented it yet, they may at any time. Adding a proxy now means zero downtime if and when the block is enforced. JioBase is free to set up and takes 5 minutes.'
+ },
+ {
+ question: 'My Vi users say the app works fine. Should I still worry?',
+ answer: 'If your app also serves users on Jio, Airtel, ACT, or BSNL, those users are already blocked. Even if Vi works today, a single ISP implementing the block means a significant portion of your user base cannot access your app.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Fix on Jio', description: 'Block confirmed on Jio', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Fix on Airtel', description: 'Block confirmed on Airtel', href: '/fix/airtel', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Why you need a proxy', description: 'The case for proxy infrastructure', href: '/blog/why-indian-developers-need-supabase-proxy', badge: 'Blog', badgeColor: 'amber' },
+ { title: 'India status', description: 'Check current block status', href: '/india-status', badge: 'Status', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Supabase on Vodafone Idea (Vi) - Block Status & Fix | JioBase',
+ metaDescription: 'Is Supabase blocked on Vodafone Idea (Vi)? Check status and proactively protect your app with a reverse proxy. Free setup, no VPN needed.',
+ metaKeywords: 'supabase vodafone idea, supabase vi blocked, supabase vi india, vodafone idea supabase fix'
+ }
+];
+
+// === Error Pages Data ===
+
+export const ERROR_PAGES: ErrorPageData[] = [
+ {
+ type: 'error',
+ slug: 'err-connection-timed-out',
+ errorCode: 'ERR_CONNECTION_TIMED_OUT',
+ displayName: 'ERR_CONNECTION_TIMED_OUT',
+ whatItMeans: 'ERR_CONNECTION_TIMED_OUT means your browser tried to connect to a server but the server did not respond within the timeout period. The connection attempt was made but no response was received. This is different from a DNS error - it means the DNS resolved to an IP address, but that IP address is either unreachable or intentionally dropping connections.',
+ whyItHappens: 'In India, this error appears when your ISP (Jio, Airtel, ACT) DNS-poisons *.supabase.co domains. Instead of returning the real Supabase server IP, your ISP\'s DNS returns a sinkhole IP - an address that either does not exist or intentionally drops all connections. Your browser resolves the domain to this sinkhole IP and tries to connect, but the connection hangs until it times out. This is why the error appears after a long delay (usually 10-30 seconds) rather than immediately.',
+ diagnosticSteps: [
+ {
+ step: 'Check DNS resolution',
+ command: 'nslookup your-project.supabase.co',
+ expected: 'If blocked: returns an ISP-owned IP (e.g., 49.44.79.236 for Jio). If working: returns an AWS IP like 13.233.x.x'
+ },
+ {
+ step: 'Compare with public DNS',
+ command: 'nslookup your-project.supabase.co 8.8.8.8',
+ expected: 'Should return the real Supabase IP (AWS). If this differs from step 1, your ISP is DNS-poisoning.'
+ },
+ {
+ step: 'Test with curl and timeout',
+ command: 'curl -m 5 -v https://your-project.supabase.co/rest/v1/ \\\n -H "apikey: YOUR_ANON_KEY" 2>&1',
+ expected: 'If blocked: "Connection timed out after 5000 milliseconds". If working: HTTP 200 with JSON response.'
+ },
+ {
+ step: 'Test on a different network',
+ command: '# Disconnect WiFi, use mobile data from a different ISP\n# Or use a VPN like Cloudflare WARP\ncurl -m 5 https://your-project.supabase.co/rest/v1/ \\\n -H "apikey: YOUR_ANON_KEY"',
+ expected: 'If the request succeeds on a different network, the issue is ISP-specific DNS blocking.'
+ }
+ ],
+ faqs: [
+ {
+ question: 'Why does my Supabase app show ERR_CONNECTION_TIMED_OUT only in India?',
+ answer: 'Indian ISPs (Jio, Airtel, ACT, BSNL) are DNS-blocking *.supabase.co following a government ministry order under Section 69A. The DNS poisoning causes your browser to connect to a sinkhole IP that never responds, resulting in a connection timeout. Supabase infrastructure is fully operational - the block is at the ISP level.'
+ },
+ {
+ question: 'Can I fix ERR_CONNECTION_TIMED_OUT by changing my DNS?',
+ answer: 'On your own device, yes - switching to Google DNS (8.8.8.8) or Cloudflare DNS (1.1.1.1) bypasses the poisoned DNS and restores access for development. But your end users on these ISPs will still see the error. For a production fix, you need a reverse proxy like JioBase that routes traffic through an unblocked domain.'
+ },
+ {
+ question: 'Is ERR_CONNECTION_TIMED_OUT the same as ERR_NAME_NOT_RESOLVED?',
+ answer: 'No. ERR_NAME_NOT_RESOLVED means DNS could not find any IP for the domain at all. ERR_CONNECTION_TIMED_OUT means DNS returned an IP, but that IP did not respond. In the Indian ISP blocking case, you typically see ERR_CONNECTION_TIMED_OUT because the DNS returns a sinkhole IP that silently drops connections.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Fix on Jio', description: 'Most common ISP causing this error', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'DNS_PROBE_FINISHED_NXDOMAIN', description: 'Another common error from the block', href: '/fix/dns-probe-finished-nxdomain', badge: 'Error', badgeColor: 'red' },
+ { title: 'Test if blocked', description: 'Full diagnostic guide', href: '/blog/test-if-backend-blocked-india', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Full fix guide', description: 'Complete Supabase block fix', href: '/blog/supabase-blocked-india-fix', badge: 'Blog', badgeColor: 'brand' }
+ ],
+ metaTitle: 'Supabase ERR_CONNECTION_TIMED_OUT in India - Fix | JioBase',
+ metaDescription: 'Getting ERR_CONNECTION_TIMED_OUT with Supabase in India? Your ISP is DNS-blocking supabase.co. Here is why it happens and how to fix it in 5 minutes.',
+ metaKeywords: 'supabase ERR_CONNECTION_TIMED_OUT, supabase connection timed out india, supabase timeout jio, supabase not connecting india'
+ },
+ {
+ type: 'error',
+ slug: 'dns-probe-finished-nxdomain',
+ errorCode: 'DNS_PROBE_FINISHED_NXDOMAIN',
+ displayName: 'DNS_PROBE_FINISHED_NXDOMAIN',
+ whatItMeans: 'DNS_PROBE_FINISHED_NXDOMAIN means your browser asked the DNS server to look up a domain name and the DNS server responded that the domain does not exist (NXDOMAIN = Non-Existent Domain). This is an immediate failure - your browser does not even attempt to connect because the DNS lookup failed entirely.',
+ whyItHappens: 'Some Indian ISPs implement the Supabase block by returning NXDOMAIN instead of a sinkhole IP. When the ISP\'s DNS resolver receives a query for *.supabase.co, it responds with "this domain does not exist" rather than forwarding the query to upstream DNS servers. This causes your browser to show DNS_PROBE_FINISHED_NXDOMAIN immediately, without the long timeout you would see with connection-based blocking.',
+ diagnosticSteps: [
+ {
+ step: 'Verify the domain exists',
+ command: 'nslookup your-project.supabase.co 8.8.8.8',
+ expected: 'If the domain exists (it should), you will get a valid IP. This confirms the domain is real and your ISP is lying.'
+ },
+ {
+ step: 'Check your ISP DNS',
+ command: 'nslookup your-project.supabase.co',
+ expected: 'If your ISP is blocking: "** server can not find your-project.supabase.co: NXDOMAIN" or similar error.'
+ },
+ {
+ step: 'Try Cloudflare DNS',
+ command: 'nslookup your-project.supabase.co 1.1.1.1',
+ expected: 'Should return a valid IP, confirming the block is ISP-specific.'
+ }
+ ],
+ faqs: [
+ {
+ question: 'Does DNS_PROBE_FINISHED_NXDOMAIN mean Supabase is down?',
+ answer: 'No. Supabase is fully operational. The NXDOMAIN error means your ISP\'s DNS is falsely reporting that the domain does not exist. You can verify this by using Google DNS (8.8.8.8) or Cloudflare DNS (1.1.1.1) - the domain resolves correctly on public DNS.'
+ },
+ {
+ question: 'Why do I see this error instead of ERR_CONNECTION_TIMED_OUT?',
+ answer: 'Different ISPs implement the block differently. Some return a sinkhole IP (causing timeout), while others return NXDOMAIN (causing this error). Both are DNS-level blocks. The fix is the same - use a reverse proxy to route traffic through an unblocked domain.'
+ },
+ {
+ question: 'Can clearing browser cache fix this?',
+ answer: 'No. The error comes from your ISP\'s DNS resolver, not your browser cache. Clearing cache, cookies, or restarting your browser will not help. You need to either change your DNS for development or use a proxy for production.'
+ }
+ ],
+ relatedPages: [
+ { title: 'ERR_CONNECTION_TIMED_OUT', description: 'The other common error from ISP blocking', href: '/fix/err-connection-timed-out', badge: 'Error', badgeColor: 'red' },
+ { title: 'Fix on Jio', description: 'Most impactful ISP block', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Fix on Airtel', description: 'Block on Airtel networks', href: '/fix/airtel', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Full fix guide', description: 'Complete Supabase block fix', href: '/blog/supabase-blocked-india-fix', badge: 'Blog', badgeColor: 'brand' }
+ ],
+ metaTitle: 'Supabase DNS_PROBE_FINISHED_NXDOMAIN in India - Fix | JioBase',
+ metaDescription: 'Getting DNS_PROBE_FINISHED_NXDOMAIN with Supabase in India? Your ISP is blocking the domain. Here is what it means and how to fix it.',
+ metaKeywords: 'supabase DNS_PROBE_FINISHED_NXDOMAIN, supabase nxdomain india, supabase dns error india, supabase domain not found india'
+ },
+ {
+ type: 'error',
+ slug: 'err-name-not-resolved',
+ errorCode: 'ERR_NAME_NOT_RESOLVED',
+ displayName: 'ERR_NAME_NOT_RESOLVED',
+ whatItMeans: 'ERR_NAME_NOT_RESOLVED means your device could not translate the domain name (e.g., your-project.supabase.co) into an IP address. This is similar to DNS_PROBE_FINISHED_NXDOMAIN but may appear on different browsers or operating systems. The underlying cause is the same - the DNS lookup failed.',
+ whyItHappens: 'Indian ISPs blocking *.supabase.co can cause this error when their DNS resolvers either return NXDOMAIN, fail to respond, or return SERVFAIL for Supabase domains. The exact error message varies by browser (Chrome shows ERR_NAME_NOT_RESOLVED, Firefox shows "Hmm. We are having trouble finding that site.") but the root cause is identical - ISP-level DNS blocking.',
+ diagnosticSteps: [
+ {
+ step: 'Test DNS with nslookup',
+ command: 'nslookup your-project.supabase.co',
+ expected: 'If blocked: error message or incorrect IP. If working: valid AWS IP.'
+ },
+ {
+ step: 'Test with alternative DNS',
+ command: 'nslookup your-project.supabase.co 1.1.1.1',
+ expected: 'Should return valid IP, confirming ISP block.'
+ },
+ {
+ step: 'Flush DNS cache and retry',
+ command: '# Windows\nipconfig /flushdns\n\n# macOS\nsudo dscacheutil -flushcache\n\n# Linux\nsudo systemd-resolve --flush-caches',
+ expected: 'If the error persists after flushing, it confirms the ISP is actively blocking (not a stale cache).'
+ }
+ ],
+ faqs: [
+ {
+ question: 'Is ERR_NAME_NOT_RESOLVED the same as DNS_PROBE_FINISHED_NXDOMAIN?',
+ answer: 'Essentially yes. Both mean your device cannot resolve the domain name to an IP address. Different browsers and operating systems display different error messages for the same underlying DNS failure. The fix is identical.'
+ },
+ {
+ question: 'I see this error on my phone but not on my laptop. Why?',
+ answer: 'Your phone and laptop may be using different DNS servers. If your laptop has been configured to use Google DNS (8.8.8.8) or Cloudflare DNS (1.1.1.1), it bypasses the ISP block. Your phone on mobile data uses the ISP\'s default DNS, which is blocking supabase.co.'
+ }
+ ],
+ relatedPages: [
+ { title: 'ERR_CONNECTION_TIMED_OUT', description: 'Another common error variant', href: '/fix/err-connection-timed-out', badge: 'Error', badgeColor: 'red' },
+ { title: 'DNS_PROBE_FINISHED_NXDOMAIN', description: 'Similar DNS resolution error', href: '/fix/dns-probe-finished-nxdomain', badge: 'Error', badgeColor: 'red' },
+ { title: 'Test if blocked', description: 'Full diagnostic guide', href: '/blog/test-if-backend-blocked-india', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Quick Jio fix', description: 'Fix for the most common ISP', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' }
+ ],
+ metaTitle: 'Supabase ERR_NAME_NOT_RESOLVED in India - Fix | JioBase',
+ metaDescription: 'Getting ERR_NAME_NOT_RESOLVED with Supabase in India? Your ISP is blocking DNS for supabase.co. Here is how to fix it for your users.',
+ metaKeywords: 'supabase ERR_NAME_NOT_RESOLVED, supabase name not resolved india, supabase dns failure india'
+ }
+];
+
+// === Feature Pages Data ===
+
+export const FEATURE_PAGES: FeaturePageData[] = [
+ {
+ type: 'feature',
+ slug: 'auth-blocked',
+ featureName: 'Supabase Auth',
+ shortName: 'Auth',
+ supabasePath: '/auth/v1/',
+ whatBreaks: 'When your ISP blocks *.supabase.co, all Supabase Auth endpoints become unreachable. This means sign up, sign in, password reset, magic links, OAuth flows (Google, GitHub, etc.), session refresh, and token verification all fail. Users see infinite loading spinners, "network error" messages, or get silently logged out. Auth cookies and JWTs may still be valid locally, but any server-side verification or token refresh fails.',
+ userImpact: 'Authentication is typically the first thing a user interacts with. If Auth is blocked, new users cannot create accounts, existing users cannot log in, active sessions eventually expire without refresh, and OAuth redirects fail because the callback URL points to a blocked domain. This is a complete app lockout for affected ISP users.',
+ codeExample: `import { createClient } from '@supabase/supabase-js'
+
+// Before (blocked on Indian ISPs):
+// const supabase = createClient('https://xyz.supabase.co', 'your-anon-key')
+
+// After (proxied through JioBase):
+const supabase = createClient('https://myapp.jiobase.com', 'your-anon-key')
+
+// Auth works exactly the same - no code changes needed:
+const { data, error } = await supabase.auth.signInWithPassword({
+ email: 'user@example.com',
+ password: 'password'
+})`,
+ codeFilename: 'lib/supabase.ts',
+ faqs: [
+ {
+ question: 'Will my existing user sessions break?',
+ answer: 'Active sessions with valid JWTs will continue to work until they expire. However, token refresh will fail because it requires calling the Auth endpoint. Once the JWT expires (default: 1 hour), users will be logged out and cannot log back in. Fix the block before sessions expire.'
+ },
+ {
+ question: 'Does OAuth (Google, GitHub login) work through the proxy?',
+ answer: 'Yes. JioBase proxies all Auth endpoints including OAuth callbacks. You do not need to change your OAuth provider settings. The proxy transparently handles the redirect flow. Just swap the Supabase URL in your client code.'
+ },
+ {
+ question: 'Do I need to change my Supabase anon key?',
+ answer: 'No. Your anon key stays exactly the same. The proxy forwards all headers including the apikey. Your RLS policies, auth settings, and database rules are completely unaffected.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Storage blocked', description: 'File uploads also fail', href: '/fix/storage-blocked', badge: 'Feature', badgeColor: 'amber' },
+ { title: 'Realtime blocked', description: 'WebSocket subscriptions fail', href: '/fix/realtime-blocked', badge: 'Feature', badgeColor: 'amber' },
+ { title: 'Fix on Jio', description: 'Most common ISP causing this', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' },
+ { title: 'Full fix guide', description: 'Complete Supabase block fix', href: '/blog/supabase-blocked-india-fix', badge: 'Blog', badgeColor: 'brand' }
+ ],
+ metaTitle: 'Supabase Auth Not Working in India - Fix Login Issues | JioBase',
+ metaDescription: 'Supabase Auth blocked in India? Sign up, login, OAuth, and session refresh all fail due to ISP DNS blocking. Fix it in 5 minutes with a proxy.',
+ metaKeywords: 'supabase auth not working india, supabase login blocked india, supabase oauth india fix, supabase sign in error india'
+ },
+ {
+ type: 'feature',
+ slug: 'storage-blocked',
+ featureName: 'Supabase Storage',
+ shortName: 'Storage',
+ supabasePath: '/storage/v1/',
+ whatBreaks: 'The ISP block on *.supabase.co prevents all Supabase Storage operations. File uploads fail, file downloads time out, signed URLs cannot be generated, bucket listing returns errors, and image transformations are unreachable. Any feature in your app that depends on file storage - profile pictures, document uploads, media galleries - breaks completely.',
+ userImpact: 'Users experience broken images (placeholder icons where photos should be), failed file uploads with no clear error message, download links that hang indefinitely, and media-heavy pages that load without any media content. Apps that rely heavily on Storage (like file-sharing tools or social platforms) become essentially unusable.',
+ codeExample: `import { createClient } from '@supabase/supabase-js'
+
+// Proxied through JioBase - Storage works identically:
+const supabase = createClient('https://myapp.jiobase.com', 'your-anon-key')
+
+// Upload a file
+const { data, error } = await supabase.storage
+ .from('avatars')
+ .upload('user-123/photo.jpg', file)
+
+// Get a signed URL
+const { data: url } = await supabase.storage
+ .from('avatars')
+ .createSignedUrl('user-123/photo.jpg', 3600)`,
+ codeFilename: 'lib/storage.ts',
+ faqs: [
+ {
+ question: 'Will large file uploads work through the proxy?',
+ answer: 'Yes. JioBase streams request and response bodies, so file uploads of any size work through the proxy. Cloudflare Workers handle streaming efficiently without buffering the entire file in memory.'
+ },
+ {
+ question: 'Do signed URLs generated through the proxy work?',
+ answer: 'Yes. Signed URLs are generated server-side by Supabase and returned through the proxy. The URLs themselves point to your proxy domain, so they remain accessible to your users on blocked ISPs.'
+ },
+ {
+ question: 'Will image transformations work?',
+ answer: 'Yes. Supabase Storage image transformations (resize, crop, format conversion) are handled server-side by Supabase. The proxy forwards the transformation parameters and returns the processed image.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Auth blocked', description: 'Login and signup also affected', href: '/fix/auth-blocked', badge: 'Feature', badgeColor: 'amber' },
+ { title: 'Realtime blocked', description: 'WebSocket connections affected', href: '/fix/realtime-blocked', badge: 'Feature', badgeColor: 'amber' },
+ { title: 'Proxy tutorial', description: 'Build your own proxy', href: '/blog/proxy-supabase-cloudflare-workers', badge: 'Tutorial', badgeColor: 'purple' },
+ { title: 'Fix on Jio', description: 'Fix for Jio users', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' }
+ ],
+ metaTitle: 'Supabase Storage Not Working in India - Fix Uploads | JioBase',
+ metaDescription: 'Supabase Storage blocked in India? File uploads, downloads, and signed URLs all fail. Fix it with a one-line proxy change.',
+ metaKeywords: 'supabase storage blocked india, supabase file upload not working india, supabase storage fix india'
+ },
+ {
+ type: 'feature',
+ slug: 'realtime-blocked',
+ featureName: 'Supabase Realtime',
+ shortName: 'Realtime',
+ supabasePath: '/realtime/v1/',
+ whatBreaks: 'Supabase Realtime uses WebSocket connections to deliver live updates, presence tracking, and broadcast messages. When *.supabase.co is DNS-blocked, the WebSocket handshake fails because it starts as an HTTP upgrade request to the blocked domain. All real-time subscriptions, presence channels, and broadcast channels stop working. Your app falls silent - no live updates, no typing indicators, no online status, no collaborative features.',
+ userImpact: 'Apps that depend on real-time features become static and unresponsive. Chat applications stop receiving new messages. Collaborative documents stop syncing. Live dashboards freeze. Notification systems go silent. The app appears "stuck" or "lagging" to users, who may think the app itself is broken rather than the connection.',
+ codeExample: `import { createClient } from '@supabase/supabase-js'
+
+// Proxied through JioBase - Realtime works including WebSockets:
+const supabase = createClient('https://myapp.jiobase.com', 'your-anon-key')
+
+// Subscribe to real-time changes (works through proxy)
+const channel = supabase
+ .channel('room-1')
+ .on('postgres_changes',
+ { event: '*', schema: 'public', table: 'messages' },
+ (payload) => console.log('New message:', payload)
+ )
+ .subscribe()
+
+// Presence tracking (works through proxy)
+const presence = supabase.channel('online-users')
+presence.on('presence', { event: 'sync' }, () => {
+ console.log('Online:', presence.presenceState())
+})`,
+ codeFilename: 'lib/realtime.ts',
+ faqs: [
+ {
+ question: 'Does JioBase support WebSocket proxying?',
+ answer: 'Yes. JioBase fully proxies WebSocket connections using Cloudflare\'s WebSocketPair API. Supabase Realtime subscriptions, presence, and broadcast all work through the proxy with minimal latency overhead (1-5ms).'
+ },
+ {
+ question: 'Will the DIY Cloudflare Worker also proxy WebSockets?',
+ answer: 'The basic Worker from our generator tool handles HTTP only. WebSocket proxying requires additional code using the WebSocketPair API. JioBase\'s managed proxy includes full WebSocket support out of the box.'
+ },
+ {
+ question: 'How much latency does the proxy add to real-time events?',
+ answer: 'Typically 1-5ms. Cloudflare Workers execute at the edge location closest to the user, so the additional hop is negligible. This is far less than VPN overhead (50-200ms+) and imperceptible in most real-time applications.'
+ }
+ ],
+ relatedPages: [
+ { title: 'Auth blocked', description: 'Login and signup also fail', href: '/fix/auth-blocked', badge: 'Feature', badgeColor: 'amber' },
+ { title: 'Storage blocked', description: 'File operations also blocked', href: '/fix/storage-blocked', badge: 'Feature', badgeColor: 'amber' },
+ { title: 'Proxy tutorial', description: 'Build a proxy with WebSocket support', href: '/blog/proxy-supabase-cloudflare-workers', badge: 'Tutorial', badgeColor: 'purple' },
+ { title: 'Fix on Jio', description: 'Fix for Jio users', href: '/fix/jio', badge: 'ISP Fix', badgeColor: 'brand' }
+ ],
+ metaTitle: 'Supabase Realtime Not Working in India - Fix WebSockets | JioBase',
+ metaDescription: 'Supabase Realtime and WebSocket subscriptions blocked in India? Live updates, presence, and broadcast all fail. Fix with a WebSocket-capable proxy.',
+ metaKeywords: 'supabase realtime blocked india, supabase websocket not working india, supabase live updates india fix'
+ }
+];
+
+// === Framework Pages Data ===
+
+export const FRAMEWORK_PAGES: FrameworkPageData[] = [
+ {
+ slug: 'nextjs',
+ name: 'Next.js',
+ shortName: 'nextjs',
+ language: 'TypeScript',
+ envPrefix: 'NEXT_PUBLIC_',
+ initFile: 'lib/supabase.ts',
+ envFile: '.env.local',
+ codeBefore: `// lib/supabase.ts
+import { createClient } from '@supabase/supabase-js'
+
+const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
+const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
+
+export const supabase = createClient(supabaseUrl, supabaseKey)`,
+ codeAfter: `// .env.local
+# Before (blocked):
+# NEXT_PUBLIC_SUPABASE_URL=https://xyz.supabase.co
+
+# After (proxied through JioBase):
+NEXT_PUBLIC_SUPABASE_URL=https://myapp.jiobase.com
+NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key`,
+ packageManager: 'npm',
+ additionalSteps: [
+ 'If you use Supabase in Server Components or API routes, ensure the server-side also uses the proxied URL. Next.js server-side code runs on your hosting provider (Vercel, etc.) which may not be affected by the ISP block, but using the proxy URL everywhere keeps your setup consistent.',
+ 'For SSR with createServerClient from @supabase/ssr, use the same NEXT_PUBLIC_SUPABASE_URL environment variable. The proxy handles both client-side and server-side requests identically.',
+ 'If you use next/image with Supabase Storage URLs, update your next.config.js remotePatterns to include your JioBase domain.'
+ ],
+ faqs: [
+ {
+ question: 'Do I need to change my Next.js API routes?',
+ answer: 'Only if they reference the Supabase URL directly. If your API routes use the same environment variable (NEXT_PUBLIC_SUPABASE_URL), just changing the env value is enough. No code changes needed.'
+ },
+ {
+ question: 'Will Supabase SSR (@supabase/ssr) work with the proxy?',
+ answer: 'Yes. The @supabase/ssr package uses the same createClient pattern. Point it at your JioBase URL and everything works - cookie-based auth, server-side data fetching, and middleware auth checks.'
+ },
+ {
+ question: 'Does this work on Vercel, Netlify, and Cloudflare?',
+ answer: 'Yes. The proxy URL works from any hosting provider. Your server-side code may not even need the proxy (servers are not affected by ISP blocks), but using the proxy URL consistently avoids confusion and works everywhere.'
+ }
+ ],
+ relatedGuides: [
+ { title: 'React guide', description: 'Vite + React setup', href: '/guides/react', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'SvelteKit guide', description: 'SvelteKit proxy setup', href: '/guides/sveltekit', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Full proxy tutorial', description: 'Build your own Worker', href: '/blog/proxy-supabase-cloudflare-workers', badge: 'Tutorial', badgeColor: 'purple' },
+ { title: 'Worker generator', description: 'Generate proxy code instantly', href: '/tools/worker-generator', badge: 'Tool', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Fix Supabase in Next.js for Indian Users - Proxy Guide | JioBase',
+ metaDescription: 'Supabase blocked in India? Fix your Next.js app with a one-line env change. Works with App Router, Pages Router, SSR, and API routes.',
+ metaKeywords: 'nextjs supabase proxy india, next.js supabase blocked fix, supabase next.js india'
+ },
+ {
+ slug: 'react',
+ name: 'React (Vite)',
+ shortName: 'react',
+ language: 'TypeScript',
+ envPrefix: 'VITE_',
+ initFile: 'src/lib/supabase.ts',
+ envFile: '.env',
+ codeBefore: `// src/lib/supabase.ts
+import { createClient } from '@supabase/supabase-js'
+
+const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
+const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY
+
+export const supabase = createClient(supabaseUrl, supabaseKey)`,
+ codeAfter: `// .env
+# Before (blocked):
+# VITE_SUPABASE_URL=https://xyz.supabase.co
+
+# After (proxied through JioBase):
+VITE_SUPABASE_URL=https://myapp.jiobase.com
+VITE_SUPABASE_ANON_KEY=your-anon-key`,
+ packageManager: 'npm',
+ additionalSteps: [
+ 'React apps built with Vite are fully client-side, so the ISP block affects 100% of your users on blocked networks. A proxy is essential.',
+ 'If you use Create React App (CRA) instead of Vite, the env prefix is REACT_APP_ instead of VITE_. Update accordingly.',
+ 'After changing the env variable, rebuild and redeploy your app. The Supabase client reads the URL at build time, so a restart or rebuild is required.'
+ ],
+ faqs: [
+ {
+ question: 'I use Create React App, not Vite. Does this still work?',
+ answer: 'Yes. The only difference is the environment variable prefix. CRA uses REACT_APP_ (e.g., REACT_APP_SUPABASE_URL) while Vite uses VITE_. The proxy setup and Supabase client code are identical.'
+ },
+ {
+ question: 'Do I need to rebuild my React app after changing the URL?',
+ answer: 'Yes. Vite and CRA both inline environment variables at build time. After updating the SUPABASE_URL in your .env file, you need to rebuild (npm run build) and redeploy. The change takes effect immediately for all users after redeployment.'
+ },
+ {
+ question: 'Will React Query / TanStack Query work with the proxy?',
+ answer: 'Yes. React Query works at the data-fetching layer above Supabase. It does not care what URL the Supabase client connects to. The proxy is transparent to all client-side libraries.'
+ }
+ ],
+ relatedGuides: [
+ { title: 'Next.js guide', description: 'Next.js SSR setup', href: '/guides/nextjs', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Flutter guide', description: 'Flutter/Dart setup', href: '/guides/flutter', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Full proxy tutorial', description: 'Build your own Worker', href: '/blog/proxy-supabase-cloudflare-workers', badge: 'Tutorial', badgeColor: 'purple' },
+ { title: 'Worker generator', description: 'Generate proxy code', href: '/tools/worker-generator', badge: 'Tool', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Fix Supabase in React for Indian Users - Proxy Guide | JioBase',
+ metaDescription: 'Supabase blocked in India? Fix your React (Vite/CRA) app with a one-line env change. Works with all React libraries and state managers.',
+ metaKeywords: 'react supabase proxy india, react supabase blocked fix, vite supabase india, supabase react india'
+ },
+ {
+ slug: 'flutter',
+ name: 'Flutter',
+ shortName: 'flutter',
+ language: 'Dart',
+ envPrefix: '',
+ initFile: 'lib/supabase.dart',
+ envFile: 'lib/constants.dart',
+ codeBefore: `// lib/supabase.dart
+import 'package:supabase_flutter/supabase_flutter.dart';
+
+Future initSupabase() async {
+ await Supabase.initialize(
+ url: 'https://xyz.supabase.co',
+ anonKey: 'your-anon-key',
+ );
+}
+
+final supabase = Supabase.instance.client;`,
+ codeAfter: `// lib/supabase.dart
+import 'package:supabase_flutter/supabase_flutter.dart';
+
+Future initSupabase() async {
+ await Supabase.initialize(
+ // Proxied through JioBase:
+ url: 'https://myapp.jiobase.com',
+ anonKey: 'your-anon-key',
+ );
+}
+
+final supabase = Supabase.instance.client;`,
+ packageManager: 'flutter pub',
+ additionalSteps: [
+ 'Flutter apps run on the user\'s device (mobile or web), so the ISP block directly affects your Indian users. This is especially critical for Android apps since most Indian Android users are on Jio or Airtel.',
+ 'For Flutter web builds, the fix is identical - the supabase_flutter package uses the same URL configuration.',
+ 'After changing the URL, rebuild your app (flutter build apk / flutter build web) and publish an update. Existing app installations will continue to fail until they update.'
+ ],
+ faqs: [
+ {
+ question: 'Do I need to publish a new app version to the Play Store?',
+ answer: 'If the Supabase URL is hardcoded in your Dart code, yes - you need to publish an update. Consider using a remote config or environment variable approach for future flexibility, so you can change the URL without an app update.'
+ },
+ {
+ question: 'Does the supabase_flutter package work with a proxy URL?',
+ answer: 'Yes. The supabase_flutter package does not validate the URL format. It works with any URL that responds with the Supabase API format. Simply replace the supabase.co URL with your JioBase proxy URL.'
+ },
+ {
+ question: 'Will Supabase Realtime work in my Flutter app through the proxy?',
+ answer: 'Yes. JioBase proxies WebSocket connections. The supabase_flutter package handles the WebSocket upgrade automatically, and the proxy transparently forwards it. Realtime subscriptions, presence, and broadcast all work.'
+ }
+ ],
+ relatedGuides: [
+ { title: 'React Native guide', description: 'React Native/Expo setup', href: '/guides/react-native', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'React guide', description: 'React web app setup', href: '/guides/react', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Full fix guide', description: 'Complete block fix guide', href: '/blog/supabase-blocked-india-fix', badge: 'Blog', badgeColor: 'brand' },
+ { title: 'Worker generator', description: 'DIY proxy option', href: '/tools/worker-generator', badge: 'Tool', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Fix Supabase in Flutter for Indian Users - Proxy Guide | JioBase',
+ metaDescription: 'Supabase blocked in India? Fix your Flutter app (Android, iOS, Web) by changing one URL. Works with supabase_flutter package.',
+ metaKeywords: 'flutter supabase proxy india, flutter supabase blocked fix, supabase flutter india, dart supabase india'
+ },
+ {
+ slug: 'sveltekit',
+ name: 'SvelteKit',
+ shortName: 'sveltekit',
+ language: 'TypeScript',
+ envPrefix: 'PUBLIC_',
+ initFile: 'src/lib/supabase.ts',
+ envFile: '.env',
+ codeBefore: `// src/lib/supabase.ts
+import { createClient } from '@supabase/supabase-js'
+import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public'
+
+export const supabase = createClient(
+ PUBLIC_SUPABASE_URL,
+ PUBLIC_SUPABASE_ANON_KEY
+)`,
+ codeAfter: `# .env
+# Before (blocked):
+# PUBLIC_SUPABASE_URL=https://xyz.supabase.co
+
+# After (proxied through JioBase):
+PUBLIC_SUPABASE_URL=https://myapp.jiobase.com
+PUBLIC_SUPABASE_ANON_KEY=your-anon-key`,
+ packageManager: 'npm',
+ additionalSteps: [
+ 'SvelteKit uses $env/static/public for client-exposed variables and $env/static/private for server-only variables. Use the PUBLIC_ prefixed URL for client-side Supabase calls.',
+ 'If you use server-side load functions (+page.server.ts) with Supabase, the server may not be affected by ISP blocks. But using the proxy URL everywhere ensures consistency.',
+ 'After changing the env, restart your dev server (npm run dev) and rebuild for production.'
+ ],
+ faqs: [
+ {
+ question: 'Does this work with SvelteKit SSR?',
+ answer: 'Yes. Server-side rendering happens on your hosting provider (Vercel, Cloudflare, etc.) which is not affected by Indian ISP blocks. But client-side hydration and subsequent API calls happen in the browser, where the block applies. Using the proxy URL for all calls ensures both SSR and CSR work.'
+ },
+ {
+ question: 'I use @supabase/ssr with SvelteKit. Does the proxy work?',
+ answer: 'Yes. The @supabase/ssr package creates a Supabase client that works identically with a proxy URL. Cookie-based auth, server hooks, and load functions all work through JioBase.'
+ },
+ {
+ question: 'Can I deploy this on Cloudflare Pages?',
+ answer: 'Yes. SvelteKit with adapter-cloudflare works perfectly with JioBase. In fact, JioBase itself is built on SvelteKit + Cloudflare Pages. The proxy URL is just a configuration change.'
+ }
+ ],
+ relatedGuides: [
+ { title: 'Next.js guide', description: 'Next.js SSR setup', href: '/guides/nextjs', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Nuxt guide', description: 'Nuxt.js setup', href: '/guides/nuxt', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Full proxy tutorial', description: 'Build your own proxy', href: '/blog/proxy-supabase-cloudflare-workers', badge: 'Tutorial', badgeColor: 'purple' },
+ { title: 'Supabase alternatives', description: 'Compare backend options', href: '/blog/supabase-alternatives-india', badge: 'Comparison', badgeColor: 'purple' }
+ ],
+ metaTitle: 'Fix Supabase in SvelteKit for Indian Users - Proxy Guide | JioBase',
+ metaDescription: 'Supabase blocked in India? Fix your SvelteKit app with a one-line env change. Works with SSR, CSR, and @supabase/ssr.',
+ metaKeywords: 'sveltekit supabase proxy india, sveltekit supabase blocked fix, svelte supabase india'
+ },
+ {
+ slug: 'nuxt',
+ name: 'Nuxt.js',
+ shortName: 'nuxt',
+ language: 'TypeScript',
+ envPrefix: 'NUXT_PUBLIC_',
+ initFile: 'plugins/supabase.ts',
+ envFile: '.env',
+ codeBefore: `// plugins/supabase.ts (or nuxt.config.ts for @nuxtjs/supabase)
+export default defineNuxtConfig({
+ modules: ['@nuxtjs/supabase'],
+ supabase: {
+ url: 'https://xyz.supabase.co',
+ key: 'your-anon-key'
+ }
+})`,
+ codeAfter: `// .env
+# Before (blocked):
+# SUPABASE_URL=https://xyz.supabase.co
+
+# After (proxied through JioBase):
+SUPABASE_URL=https://myapp.jiobase.com
+SUPABASE_KEY=your-anon-key`,
+ packageManager: 'npm',
+ additionalSteps: [
+ 'If you use the @nuxtjs/supabase module, the URL and key are read from environment variables by default. Just update your .env file.',
+ 'For manual Supabase client setup (without the module), update the URL wherever you call createClient().',
+ 'Nuxt 3\'s server-side rendering is not affected by ISP blocks, but client-side hydration and API calls are. Use the proxy URL for all calls.'
+ ],
+ faqs: [
+ {
+ question: 'Does @nuxtjs/supabase work with a proxy URL?',
+ answer: 'Yes. The @nuxtjs/supabase module passes the URL directly to createClient. Any URL that serves the Supabase API format works, including JioBase proxy URLs.'
+ },
+ {
+ question: 'Do I need to change my nuxt.config.ts?',
+ answer: 'If you hardcoded the URL in nuxt.config.ts, move it to .env so you can change it per environment. The @nuxtjs/supabase module reads SUPABASE_URL and SUPABASE_KEY from environment variables automatically.'
+ }
+ ],
+ relatedGuides: [
+ { title: 'SvelteKit guide', description: 'SvelteKit setup', href: '/guides/sveltekit', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Next.js guide', description: 'Next.js SSR setup', href: '/guides/nextjs', badge: 'Guide', badgeColor: 'blue' },
+ { title: 'Full fix guide', description: 'Complete block fix guide', href: '/blog/supabase-blocked-india-fix', badge: 'Blog', badgeColor: 'brand' },
+ { title: 'Worker generator', description: 'DIY proxy option', href: '/tools/worker-generator', badge: 'Tool', badgeColor: 'amber' }
+ ],
+ metaTitle: 'Fix Supabase in Nuxt.js for Indian Users - Proxy Guide | JioBase',
+ metaDescription: 'Supabase blocked in India? Fix your Nuxt.js app with a one-line env change. Works with @nuxtjs/supabase module and manual setup.',
+ metaKeywords: 'nuxt supabase proxy india, nuxtjs supabase blocked fix, nuxt supabase india'
+ }
+];
+
+// === Lookup Maps ===
+
+export const FIX_PAGES_MAP = new Map();
+for (const page of ISP_PAGES) FIX_PAGES_MAP.set(page.slug, page);
+for (const page of ERROR_PAGES) FIX_PAGES_MAP.set(page.slug, page);
+for (const page of FEATURE_PAGES) FIX_PAGES_MAP.set(page.slug, page);
+
+export const FRAMEWORK_PAGES_MAP = new Map();
+for (const page of FRAMEWORK_PAGES) FRAMEWORK_PAGES_MAP.set(page.slug, page);
+
+// === Slug Arrays (for sitemap) ===
+
+export const ALL_FIX_SLUGS = [
+ ...ISP_PAGES.map(p => p.slug),
+ ...ERROR_PAGES.map(p => p.slug),
+ ...FEATURE_PAGES.map(p => p.slug)
+];
+
+export const ALL_FRAMEWORK_SLUGS = FRAMEWORK_PAGES.map(p => p.slug);
diff --git a/apps/web/src/routes/+layout.svelte b/apps/web/src/routes/+layout.svelte
index 71f283a..9dd328e 100644
--- a/apps/web/src/routes/+layout.svelte
+++ b/apps/web/src/routes/+layout.svelte
@@ -1,6 +1,5 @@
-
+
+
+
+
+
JioBase
diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte
index 1c2f6a1..d773606 100644
--- a/apps/web/src/routes/+page.svelte
+++ b/apps/web/src/routes/+page.svelte
@@ -1,12 +1,70 @@
JioBase - Fix Supabase Blocked in India | Bypass Jio, Airtel DNS Block
+ {@html ``}
+
+
@@ -370,16 +428,23 @@
-
Free & Open Source
+
Built by one dev. Funded by coffee.
- 100% free. For now.
+ 100% free. Seriously.
-
- JioBase is a community project built to help Indian developers affected by the Supabase DNS block. Everything is free for the time being - no limits, no paid tiers.
+
+
+
+
+
+ I'm Sunith, an indie developer from India. I built JioBase because the Supabase block broke my own production app — and I knew thousands of other devs were stuck too.
+
+
+ It's free because I think fixing infrastructure shouldn't cost you anything. But running this isn't free for me — every proxied request costs real money on Cloudflare. If JioBase saved your app, a $3 coffee genuinely helps keep the lights on.
- Running on Cloudflare Workers costs money. If JioBase saves you time, consider supporting the project.
+ Every $3 coffee directly pays for Cloudflare Workers that keep your app online.